blob: 7e06cae7469a77da78c614171a0ac7249620f8ec [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
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000174 mutexPLastTxMeInstance sync.RWMutex
mpagenko01e726e2020-10-23 09:45:29 +0000175 pLastTxMeInstance *me.ManagedEntity
mpagenkofc4f56e2020-11-04 17:17:49 +0000176 requestEventOffset uint8
mpagenko551a4d42020-12-08 18:09:20 +0000177 TpIDWaitingFor uint8
mpagenkobb47bc22021-04-20 13:29:09 +0000178 signalOnFlowDelete bool
179 flowDeleteChannel chan<- bool
mpagenkof1fc3862021-02-16 10:09:52 +0000180 //cookie value that indicates that a rule to add is delayed by waiting for deletion of some other existing rule with the same cookie
181 delayNewRuleCookie uint64
mpagenkodff5dda2020-08-28 11:52:01 +0000182}
183
mpagenko01e726e2020-10-23 09:45:29 +0000184//NewUniVlanConfigFsm is the 'constructor' for the state machine to config the PON ANI ports
185// of ONU UNI ports via OMCI
dbainbri4d3a0dc2020-12-02 00:33:42 +0000186func NewUniVlanConfigFsm(ctx context.Context, apDeviceHandler *deviceHandler, apDevOmciCC *omciCC, apUniPort *onuUniPort,
mpagenko551a4d42020-12-08 18:09:20 +0000187 apUniTechProf *onuUniTechProf, apOnuDB *onuDeviceDB, aTechProfileID uint8,
mpagenko01e726e2020-10-23 09:45:29 +0000188 aRequestEvent OnuDeviceEvent, aName string, aCommChannel chan Message, aAcceptIncrementalEvto bool,
189 aCookieSlice []uint64, aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) *UniVlanConfigFsm {
mpagenkodff5dda2020-08-28 11:52:01 +0000190 instFsm := &UniVlanConfigFsm{
191 pDeviceHandler: apDeviceHandler,
mpagenko01e726e2020-10-23 09:45:29 +0000192 deviceID: apDeviceHandler.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +0000193 pOmciCC: apDevOmciCC,
194 pOnuUniPort: apUniPort,
195 pUniTechProf: apUniTechProf,
196 pOnuDB: apOnuDB,
mpagenkodff5dda2020-08-28 11:52:01 +0000197 requestEvent: aRequestEvent,
198 acceptIncrementalEvtoOption: aAcceptIncrementalEvto,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000199 numUniFlows: 0,
200 configuredUniFlow: 0,
mpagenko01e726e2020-10-23 09:45:29 +0000201 numRemoveFlows: 0,
mpagenko2418ab02020-11-12 12:58:06 +0000202 clearPersistency: true,
mpagenkodff5dda2020-08-28 11:52:01 +0000203 }
204
mpagenko01e726e2020-10-23 09:45:29 +0000205 instFsm.pAdaptFsm = NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
mpagenkodff5dda2020-08-28 11:52:01 +0000206 if instFsm.pAdaptFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000207 logger.Errorw(ctx, "UniVlanConfigFsm's AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000208 "device-id": instFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000209 return nil
210 }
mpagenkodff5dda2020-08-28 11:52:01 +0000211 instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
212 vlanStDisabled,
213 fsm.Events{
214 {Name: vlanEvStart, Src: []string{vlanStDisabled}, Dst: vlanStStarting},
215 {Name: vlanEvWaitTechProf, Src: []string{vlanStStarting}, Dst: vlanStWaitingTechProf},
mpagenko535d6ef2021-02-26 13:15:34 +0000216 {Name: vlanEvCancelOutstandingConfig, Src: []string{vlanStWaitingTechProf}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000217 {Name: vlanEvContinueConfig, Src: []string{vlanStWaitingTechProf}, Dst: vlanStConfigVtfd},
218 {Name: vlanEvStartConfig, Src: []string{vlanStStarting}, Dst: vlanStConfigVtfd},
219 {Name: vlanEvRxConfigVtfd, Src: []string{vlanStConfigVtfd}, Dst: vlanStConfigEvtocd},
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000220 {Name: vlanEvRxConfigEvtocd, Src: []string{vlanStConfigEvtocd, vlanStConfigIncrFlow},
221 Dst: vlanStConfigDone},
mpagenko551a4d42020-12-08 18:09:20 +0000222 {Name: vlanEvRenew, Src: []string{vlanStConfigDone}, Dst: vlanStStarting},
223 {Name: vlanEvWaitTPIncr, Src: []string{vlanStConfigDone}, Dst: vlanStIncrFlowWaitTP},
224 {Name: vlanEvIncrFlowConfig, Src: []string{vlanStConfigDone, vlanStIncrFlowWaitTP},
225 Dst: vlanStConfigIncrFlow},
mpagenko01e726e2020-10-23 09:45:29 +0000226 {Name: vlanEvRemFlowConfig, Src: []string{vlanStConfigDone}, Dst: vlanStRemoveFlow},
227 {Name: vlanEvRemFlowDone, Src: []string{vlanStRemoveFlow}, Dst: vlanStCleanupDone},
228 {Name: vlanEvFlowDataRemoved, Src: []string{vlanStCleanupDone}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000229 /*
230 {Name: vlanEvTimeoutSimple, Src: []string{
231 vlanStCreatingDot1PMapper, vlanStCreatingMBPCD, vlanStSettingTconts, vlanStSettingDot1PMapper}, Dst: vlanStStarting},
232 {Name: vlanEvTimeoutMids, Src: []string{
233 vlanStCreatingGemNCTPs, vlanStCreatingGemIWs, vlanStSettingPQs}, Dst: vlanStStarting},
234 */
235 // exceptional treatment for all states except vlanStResetting
236 {Name: vlanEvReset, Src: []string{vlanStStarting, vlanStWaitingTechProf,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000237 vlanStConfigVtfd, vlanStConfigEvtocd, vlanStConfigDone, vlanStConfigIncrFlow,
mpagenko01e726e2020-10-23 09:45:29 +0000238 vlanStRemoveFlow, vlanStCleanupDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000239 Dst: vlanStResetting},
240 // the only way to get to resource-cleared disabled state again is via "resseting"
241 {Name: vlanEvRestart, Src: []string{vlanStResetting}, Dst: vlanStDisabled},
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000242 // transitions for reconcile handling according to VOL-3834
243 {Name: vlanEvSkipOmciConfig, Src: []string{vlanStStarting}, Dst: vlanStConfigDone},
244 {Name: vlanEvSkipOmciConfig, Src: []string{vlanStConfigDone}, Dst: vlanStConfigIncrFlow},
245 {Name: vlanEvSkipIncFlowConfig, Src: []string{vlanStConfigIncrFlow}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000246 },
mpagenkodff5dda2020-08-28 11:52:01 +0000247 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000248 "enter_state": func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(ctx, e) },
249 "enter_" + vlanStStarting: func(e *fsm.Event) { instFsm.enterConfigStarting(ctx, e) },
250 "enter_" + vlanStConfigVtfd: func(e *fsm.Event) { instFsm.enterConfigVtfd(ctx, e) },
251 "enter_" + vlanStConfigEvtocd: func(e *fsm.Event) { instFsm.enterConfigEvtocd(ctx, e) },
252 "enter_" + vlanStConfigDone: func(e *fsm.Event) { instFsm.enterVlanConfigDone(ctx, e) },
253 "enter_" + vlanStConfigIncrFlow: func(e *fsm.Event) { instFsm.enterConfigIncrFlow(ctx, e) },
254 "enter_" + vlanStRemoveFlow: func(e *fsm.Event) { instFsm.enterRemoveFlow(ctx, e) },
255 "enter_" + vlanStCleanupDone: func(e *fsm.Event) { instFsm.enterVlanCleanupDone(ctx, e) },
256 "enter_" + vlanStResetting: func(e *fsm.Event) { instFsm.enterResetting(ctx, e) },
257 "enter_" + vlanStDisabled: func(e *fsm.Event) { instFsm.enterDisabled(ctx, e) },
mpagenkodff5dda2020-08-28 11:52:01 +0000258 },
259 )
260 if instFsm.pAdaptFsm.pFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000261 logger.Errorw(ctx, "UniVlanConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000262 "device-id": instFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000263 return nil
264 }
265
dbainbri4d3a0dc2020-12-02 00:33:42 +0000266 _ = instFsm.initUniFlowParams(ctx, aTechProfileID, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000267
dbainbri4d3a0dc2020-12-02 00:33:42 +0000268 logger.Debugw(ctx, "UniVlanConfigFsm created", log.Fields{"device-id": instFsm.deviceID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000269 "accIncrEvto": instFsm.acceptIncrementalEvtoOption})
mpagenkodff5dda2020-08-28 11:52:01 +0000270 return instFsm
271}
272
mpagenko01e726e2020-10-23 09:45:29 +0000273//initUniFlowParams is a simplified form of SetUniFlowParams() used for first flow parameters configuration
mpagenko551a4d42020-12-08 18:09:20 +0000274func (oFsm *UniVlanConfigFsm) initUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +0000275 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) error {
276 loRuleParams := uniVlanRuleParams{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000277 TpID: aTpID,
278 MatchVid: uint32(aMatchVlan),
279 SetVid: uint32(aSetVlan),
280 SetPcp: uint32(aSetPcp),
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000281 }
282 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
mpagenko01e726e2020-10-23 09:45:29 +0000283 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
284 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000285
mpagenko01e726e2020-10-23 09:45:29 +0000286 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000287 //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 +0000288 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000289 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
290 } else {
291 if !oFsm.acceptIncrementalEvtoOption {
292 //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 +0000293 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000294 }
295 }
296
mpagenko01e726e2020-10-23 09:45:29 +0000297 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000298 // no prio/vid filtering requested
mpagenko01e726e2020-10-23 09:45:29 +0000299 loRuleParams.TagsToRemove = 0 //no tag pop action
300 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
301 if loRuleParams.SetPcp == cCopyPrioFromInner {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000302 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
303 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
304 // might collide with NoMatchVid/CopyPrio(/setVid) setting
305 // this was some precondition setting taken over from py adapter ..
mpagenko01e726e2020-10-23 09:45:29 +0000306 loRuleParams.SetPcp = 0
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000307 }
308 }
mpagenko01e726e2020-10-23 09:45:29 +0000309
310 loFlowParams := uniVlanFlowParams{VlanRuleParams: loRuleParams}
311 loFlowParams.CookieSlice = make([]uint64, 0)
312 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
313
314 //no mutex protection is required for initial access and adding the first flow is always possible
315 oFsm.uniVlanFlowParamsSlice = make([]uniVlanFlowParams, 0)
316 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000317 logger.Debugw(ctx, "first UniVlanConfigFsm flow added", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000318 "Cookies": oFsm.uniVlanFlowParamsSlice[0].CookieSlice,
319 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
320 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
321 "SetPcp": loRuleParams.SetPcp,
322 "device-id": oFsm.deviceID})
323 oFsm.numUniFlows = 1
324 oFsm.uniRemoveFlowsSlice = make([]uniRemoveVlanFlowParams, 0) //initially nothing to remove
325
326 //permanently store flow config for reconcile case
dbainbri4d3a0dc2020-12-02 00:33:42 +0000327 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
mpagenkof1fc3862021-02-16 10:09:52 +0000328 &oFsm.uniVlanFlowParamsSlice, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000329 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000330 return err
331 }
332
333 return nil
334}
335
mpagenko7d6bb022021-03-11 15:07:55 +0000336//CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
mpagenko73143992021-04-09 15:17:10 +0000337func (oFsm *UniVlanConfigFsm) CancelProcessing(ctx context.Context) {
mpagenko7d6bb022021-03-11 15:07:55 +0000338 //mutex protection is required for possible concurrent access to FSM members
mpagenkocf48e452021-04-23 09:23:00 +0000339 oFsm.mutexIsAwaitingResponse.Lock()
340 oFsm.isCanceled = true
mpagenko7d6bb022021-03-11 15:07:55 +0000341 if oFsm.isAwaitingResponse {
mpagenkocf48e452021-04-23 09:23:00 +0000342 //attention: for an unbuffered channel the sender is blocked until the value is received (processed)!
343 // accordingly the mutex must be released before sending to channel here (mutex acquired in receiver)
344 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000345 //use channel to indicate that the response waiting shall be aborted
346 oFsm.omciMIdsResponseReceived <- false
mpagenkocf48e452021-04-23 09:23:00 +0000347 } else {
348 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000349 }
mpagenkocf48e452021-04-23 09:23:00 +0000350
mpagenko7d6bb022021-03-11 15:07:55 +0000351 // in any case (even if it might be automatically requested by above cancellation of waiting) ensure resetting the FSM
352 pAdaptFsm := oFsm.pAdaptFsm
353 if pAdaptFsm != nil {
mpagenkobb47bc22021-04-20 13:29:09 +0000354 if fsmErr := pAdaptFsm.pFsm.Event(vlanEvReset); fsmErr != nil {
mpagenkocf48e452021-04-23 09:23:00 +0000355 logger.Errorw(ctx, "reset-event failed in UniVlanConfigFsm!",
mpagenkobb47bc22021-04-20 13:29:09 +0000356 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000357 }
mpagenko7d6bb022021-03-11 15:07:55 +0000358 }
359}
360
mpagenko551a4d42020-12-08 18:09:20 +0000361//GetWaitingTpID returns the TpId that the FSM might be waiting for continuation (0 if none)
362func (oFsm *UniVlanConfigFsm) GetWaitingTpID() uint8 {
363 //mutex protection is required for possible concurrent access to FSM members
364 oFsm.mutexFlowParams.RLock()
365 defer oFsm.mutexFlowParams.RUnlock()
366 return oFsm.TpIDWaitingFor
367}
368
mpagenko2418ab02020-11-12 12:58:06 +0000369//RequestClearPersistency sets the internal flag to not clear persistency data (false=NoClear)
370func (oFsm *UniVlanConfigFsm) RequestClearPersistency(aClear bool) {
371 //mutex protection is required for possible concurrent access to FSM members
mpagenko15ff4a52021-03-02 10:09:20 +0000372 oFsm.mutexFlowParams.Lock()
373 defer oFsm.mutexFlowParams.Unlock()
mpagenko2418ab02020-11-12 12:58:06 +0000374 oFsm.clearPersistency = aClear
375}
376
mpagenko01e726e2020-10-23 09:45:29 +0000377//SetUniFlowParams verifies on existence of flow parameters to be configured,
378// optionally udates the cookie list or appends a new flow if there is space
379// if possible the FSM is trigggerd to start with the processing
mpagenko551a4d42020-12-08 18:09:20 +0000380// ignore complexity by now
381// nolint: gocyclo
382func (oFsm *UniVlanConfigFsm) SetUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +0000383 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) error {
384 loRuleParams := uniVlanRuleParams{
385 TpID: aTpID,
386 MatchVid: uint32(aMatchVlan),
387 SetVid: uint32(aSetVlan),
388 SetPcp: uint32(aSetPcp),
389 }
390 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
391 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
392 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
393
394 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
395 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
396 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
397 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
398 } else {
399 if !oFsm.acceptIncrementalEvtoOption {
400 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
401 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
402 }
403 }
404
405 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
406 // no prio/vid filtering requested
407 loRuleParams.TagsToRemove = 0 //no tag pop action
408 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
409 if loRuleParams.SetPcp == cCopyPrioFromInner {
410 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
411 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
412 // might collide with NoMatchVid/CopyPrio(/setVid) setting
413 // this was some precondition setting taken over from py adapter ..
414 loRuleParams.SetPcp = 0
415 }
416 }
417
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000418 flowEntryMatch := false
mpagenko01e726e2020-10-23 09:45:29 +0000419 flowCookieModify := false
mpagenkof1fc3862021-02-16 10:09:52 +0000420 requestAppendRule := false
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000421 //mutex protection is required for possible concurrent access to FSM members
422 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +0000423 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
424 //TODO: Verify if using e.g. hashes for the structures here for comparison may generate
425 // countable run time optimization (perhaps with including the hash in kvStore storage?)
426 if storedUniFlowParams.VlanRuleParams == loRuleParams {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000427 flowEntryMatch = true
dbainbri4d3a0dc2020-12-02 00:33:42 +0000428 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - rule already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000429 "device-id": oFsm.deviceID})
430 var cookieMatch bool
431 for _, newCookie := range aCookieSlice { // for all cookies available in the arguments
432 cookieMatch = false
433 for _, cookie := range storedUniFlowParams.CookieSlice {
434 if cookie == newCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000435 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - and cookie already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000436 "device-id": oFsm.deviceID, "cookie": cookie})
437 cookieMatch = true
438 break //found new cookie - no further search for this requested cookie
439 }
440 }
441 if !cookieMatch {
mpagenkof1fc3862021-02-16 10:09:52 +0000442 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
443 if delayedCookie != 0 {
444 //a delay for adding the cookie to this rule is requested
445 // take care of the mutex which is already locked here, need to unlock/lock accordingly to prevent deadlock in suspension
446 oFsm.mutexFlowParams.Unlock()
447 oFsm.suspendNewRule(ctx)
448 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
449 oFsm.mutexFlowParams.Lock()
450 } else {
451 logger.Debugw(ctx, "UniVlanConfigFsm flow setting -adding new cookie", log.Fields{
452 "device-id": oFsm.deviceID, "cookie": newCookie})
453 //as range works with copies of the slice we have to write to the original slice!!
454 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
455 newCookie)
456 flowCookieModify = true
457 }
mpagenko01e726e2020-10-23 09:45:29 +0000458 }
459 } //for all new cookies
460 break // found rule - no further rule search
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000461 }
462 }
mpagenkof1fc3862021-02-16 10:09:52 +0000463 oFsm.mutexFlowParams.Unlock()
464
465 if !flowEntryMatch { //it is (was) a new rule
466 delayedCookie := oFsm.suspendIfRequiredNewRule(ctx, aCookieSlice)
467 requestAppendRule = true //default assumption here is that rule is to be appended
468 flowCookieModify = true //and that the the flow data base is to be updated
469 if delayedCookie != 0 { //it was suspended
470 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
471 }
472 }
473 kvStoreWrite := false //default setting is to not write to kvStore immediately - will be done on FSM execution finally
474 if requestAppendRule {
475 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000476 if oFsm.numUniFlows < cMaxAllowedFlows {
mpagenko01e726e2020-10-23 09:45:29 +0000477 loFlowParams := uniVlanFlowParams{VlanRuleParams: loRuleParams}
478 loFlowParams.CookieSlice = make([]uint64, 0)
479 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
480 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000481 logger.Debugw(ctx, "UniVlanConfigFsm flow add", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000482 "Cookies": oFsm.uniVlanFlowParamsSlice[oFsm.numUniFlows].CookieSlice,
483 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
484 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
Girish Gowdra041dcb32020-11-16 16:54:30 -0800485 "SetPcp": loRuleParams.SetPcp, "numberofFlows": oFsm.numUniFlows + 1,
mpagenko01e726e2020-10-23 09:45:29 +0000486 "device-id": oFsm.deviceID})
487
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000488 oFsm.numUniFlows++
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000489 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
490
491 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
492 logger.Debugw(ctx, "reconciling - skip omci-config of additional vlan rule",
493 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
mpagenkobb47bc22021-04-20 13:29:09 +0000494 //attention: take care to release the mutexFlowParams when calling the FSM directly -
495 // synchronous FSM 'event/state' functions may rely on this mutex
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000496 oFsm.mutexFlowParams.Unlock()
497 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
mpagenkobb47bc22021-04-20 13:29:09 +0000498 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvSkipOmciConfig); fsmErr != nil {
499 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
500 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
501 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000502 }
503 return nil
504 }
mpagenko01e726e2020-10-23 09:45:29 +0000505 // note: theoretical it would be possible to clear the same rule from the remove slice
506 // (for entries that have not yet been started with removal)
507 // but that is getting quite complicated - maybe a future optimization in case it should prove reasonable
508 // 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 +0000509
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000510 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
511 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
mpagenko551a4d42020-12-08 18:09:20 +0000512 if oFsm.configuredUniFlow == 0 {
513 // this is a restart with a complete new flow, we can re-use the initial flow config control
514 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenkobb47bc22021-04-20 13:29:09 +0000515 //attention: take care to release the mutexFlowParams when calling the FSM directly -
516 // synchronous FSM 'event/state' functions may rely on this mutex
517 oFsm.mutexFlowParams.Unlock()
518 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvRenew); fsmErr != nil {
519 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
520 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
521 }
mpagenko551a4d42020-12-08 18:09:20 +0000522 } else {
523 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000524 //store the actual rule that shall be worked upon in the following transient states
525 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +0000526 //tpId of the next rule to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000527 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko551a4d42020-12-08 18:09:20 +0000528 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, tpID)
529 oFsm.TpIDWaitingFor = tpID
mpagenko9a304ea2020-12-16 15:54:01 +0000530 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request (on setConfig)", log.Fields{
531 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
532 "set-Vlan": oFsm.actualUniVlanConfigRule.SetVid, "tp-id": tpID, "ProfDone": loTechProfDone})
mpagenkobb47bc22021-04-20 13:29:09 +0000533
534 //attention: take care to release the mutexFlowParams when calling the FSM directly -
535 // synchronous FSM 'event/state' functions may rely on this mutex
536 oFsm.mutexFlowParams.Unlock()
537 var fsmErr error
538 if loTechProfDone {
539 // let the vlan processing continue with next rule
540 fsmErr = pConfigVlanStateBaseFsm.Event(vlanEvIncrFlowConfig)
541 } else {
542 // set to waiting for Techprofile
543 fsmErr = pConfigVlanStateBaseFsm.Event(vlanEvWaitTPIncr)
544 }
545 if fsmErr != nil {
546 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
547 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
548 }
mpagenko551a4d42020-12-08 18:09:20 +0000549 }
mpagenkobb47bc22021-04-20 13:29:09 +0000550 } else {
551 // if not in the appropriate state a new entry will be automatically considered later
552 // when the configDone state is reached
553 oFsm.mutexFlowParams.Unlock()
554 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000555 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000556 logger.Errorw(ctx, "UniVlanConfigFsm flow limit exceeded", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000557 "device-id": oFsm.deviceID, "flow-number": oFsm.numUniFlows})
mpagenko15ff4a52021-03-02 10:09:20 +0000558 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000559 return fmt.Errorf(" UniVlanConfigFsm flow limit exceeded %s", oFsm.deviceID)
560 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000561 } else {
562 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
mpagenkof1fc3862021-02-16 10:09:52 +0000563 kvStoreWrite = true // ensure actual data write to kvStore immediately (no FSM activity)
mpagenko15ff4a52021-03-02 10:09:20 +0000564 oFsm.mutexFlowParams.RLock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000565 if oFsm.numUniFlows == oFsm.configuredUniFlow {
566 //all requested rules really have been configured
567 // state transition notification is checked in deviceHandler
mpagenko15ff4a52021-03-02 10:09:20 +0000568 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000569 if oFsm.pDeviceHandler != nil {
570 //also the related TechProfile was already configured
dbainbri4d3a0dc2020-12-02 00:33:42 +0000571 logger.Debugw(ctx, "UniVlanConfigFsm rule already set - send immediate add-success event for reason update", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +0000572 "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +0000573 // success indication without the need to write to kvStore (done already below with updated data from storePersUniFlowConfig())
574 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetAddNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000575 }
576 } else {
577 // avoid device reason update as the rule config connected to this flow may still be in progress
578 // and the device reason should only be updated on success of rule config
dbainbri4d3a0dc2020-12-02 00:33:42 +0000579 logger.Debugw(ctx, "UniVlanConfigFsm rule already set but configuration ongoing, suppress early add-success event for reason update",
mpagenkofc4f56e2020-11-04 17:17:49 +0000580 log.Fields{"device-id": oFsm.deviceID,
581 "NumberofRules": oFsm.numUniFlows, "Configured rules": oFsm.configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +0000582 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000583 }
584 }
mpagenko01e726e2020-10-23 09:45:29 +0000585
mpagenkof1fc3862021-02-16 10:09:52 +0000586 if flowCookieModify { // some change was done to the flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000587 //permanently store flow config for reconcile case
mpagenko15ff4a52021-03-02 10:09:20 +0000588 oFsm.mutexFlowParams.RLock()
mpagenkof1fc3862021-02-16 10:09:52 +0000589 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
590 &oFsm.uniVlanFlowParamsSlice, kvStoreWrite); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +0000591 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000592 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000593 return err
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000594 }
mpagenko15ff4a52021-03-02 10:09:20 +0000595 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000596 }
597 return nil
598}
599
mpagenkof1fc3862021-02-16 10:09:52 +0000600// VOL-3828 flow config sequence workaround ########### start ##########
601func (oFsm *UniVlanConfigFsm) delayNewRuleForCookie(ctx context.Context, aCookieSlice []uint64) uint64 {
602 //assumes mutexFlowParams.Lock() protection from caller!
603 if oFsm.delayNewRuleCookie == 0 && len(aCookieSlice) == 1 {
604 // if not already waiting, limitation for this workaround is to just have one overlapping cookie/rule
605 // suspend check is done only of there is only one cookie in the request
606 // background: more elements only expected in reconcile use case, where no conflicting sequence is to be expected
607 newCookie := aCookieSlice[0]
608 for _, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
609 for _, cookie := range storedUniFlowParams.CookieSlice {
610 if cookie == newCookie {
611 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - new cookie still exists for some rule", log.Fields{
612 "device-id": oFsm.deviceID, "cookie": cookie, "exists with SetVlan": storedUniFlowParams.VlanRuleParams.SetVid})
613 oFsm.delayNewRuleCookie = newCookie
614 return newCookie //found new cookie in some existing rule
615 }
616 } // for all stored cookies of the actual inspected rule
617 } //for all rules
618 }
619 return 0 //no delay requested
620}
621func (oFsm *UniVlanConfigFsm) suspendNewRule(ctx context.Context) {
622 oFsm.mutexFlowParams.RLock()
623 logger.Infow(ctx, "Need to suspend adding this rule as long as the cookie is still connected to some other rule", log.Fields{
624 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
625 oFsm.mutexFlowParams.RUnlock()
626 select {
627 case <-oFsm.chCookieDeleted:
628 logger.Infow(ctx, "resume adding this rule after having deleted cookie in some other rule", log.Fields{
629 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000630 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
mpagenkof1fc3862021-02-16 10:09:52 +0000631 logger.Errorw(ctx, "timeout waiting for deletion of cookie in some other rule, just try to continue", log.Fields{
632 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
633 }
634 oFsm.mutexFlowParams.Lock()
635 oFsm.delayNewRuleCookie = 0
636 oFsm.mutexFlowParams.Unlock()
637}
638func (oFsm *UniVlanConfigFsm) suspendIfRequiredNewRule(ctx context.Context, aCookieSlice []uint64) uint64 {
639 oFsm.mutexFlowParams.Lock()
640 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
641 oFsm.mutexFlowParams.Unlock()
642
643 if delayedCookie != 0 {
644 oFsm.suspendNewRule(ctx)
645 }
646 return delayedCookie
647}
648
649//returns flowModified, RuleAppendRequest
650func (oFsm *UniVlanConfigFsm) reviseFlowConstellation(ctx context.Context, aCookie uint64, aUniVlanRuleParams uniVlanRuleParams) (bool, bool) {
651 flowEntryMatch := false
652 oFsm.mutexFlowParams.Lock()
653 defer oFsm.mutexFlowParams.Unlock()
654 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
655 if storedUniFlowParams.VlanRuleParams == aUniVlanRuleParams {
656 flowEntryMatch = true
657 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - rule already exists", log.Fields{
658 "device-id": oFsm.deviceID})
659 cookieMatch := false
660 for _, cookie := range storedUniFlowParams.CookieSlice {
661 if cookie == aCookie {
662 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - and cookie already exists", log.Fields{
663 "device-id": oFsm.deviceID, "cookie": cookie})
664 cookieMatch = true
665 break //found new cookie - no further search for this requested cookie
666 }
667 }
668 if !cookieMatch {
669 logger.Debugw(ctx, "UniVlanConfigFsm flow revise -adding new cookie", log.Fields{
670 "device-id": oFsm.deviceID, "cookie": aCookie})
671 //as range works with copies of the slice we have to write to the original slice!!
672 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
673 aCookie)
674 return true, false //flowModified, NoRuleAppend
675 }
676 break // found rule - no further rule search
677 }
678 }
679 if !flowEntryMatch { //it is a new rule
680 return true, true //flowModified, RuleAppend
681 }
682 return false, false //flowNotModified, NoRuleAppend
683}
684
685// VOL-3828 flow config sequence workaround ########### end ##########
686
mpagenko01e726e2020-10-23 09:45:29 +0000687//RemoveUniFlowParams verifies on existence of flow cookie,
688// if found removes cookie from flow cookie list and if this is empty
689// initiates removal of the flow related configuration from the ONU (via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000690func (oFsm *UniVlanConfigFsm) RemoveUniFlowParams(ctx context.Context, aCookie uint64) error {
mpagenkof1fc3862021-02-16 10:09:52 +0000691 var deletedCookie uint64
mpagenko01e726e2020-10-23 09:45:29 +0000692 flowCookieMatch := false
693 //mutex protection is required for possible concurrent access to FSM members
694 oFsm.mutexFlowParams.Lock()
695 defer oFsm.mutexFlowParams.Unlock()
mpagenkof1fc3862021-02-16 10:09:52 +0000696remove_loop:
mpagenko01e726e2020-10-23 09:45:29 +0000697 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
698 for i, cookie := range storedUniFlowParams.CookieSlice {
699 if cookie == aCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000700 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - cookie found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000701 "device-id": oFsm.deviceID, "cookie": cookie})
702 flowCookieMatch = true
mpagenkof1fc3862021-02-16 10:09:52 +0000703 deletedCookie = aCookie
704 kvStoreWrite := false //default setting is to not write to kvStore immediately - will be done on FSM execution finally
mpagenko01e726e2020-10-23 09:45:29 +0000705 //remove the cookie from the cookie slice and verify it is getting empty
706 if len(storedUniFlowParams.CookieSlice) == 1 {
mpagenko535d6ef2021-02-26 13:15:34 +0000707 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
708 var cancelPendingConfig bool = false
709 var loRemoveParams uniRemoveVlanFlowParams = uniRemoveVlanFlowParams{}
dbainbri4d3a0dc2020-12-02 00:33:42 +0000710 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - full flow removal", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000711 "device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +0000712 //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 +0000713 // as the one still waiting in the FSM as toAdd but waiting for TechProfileConfig
mpagenko15ff4a52021-03-02 10:09:20 +0000714 // 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 +0000715 // if the Fsm is in some other transient (config) state, we will reach the DelRequest later and correctly process it then
716 if pConfigVlanStateBaseFsm.Is(vlanStWaitingTechProf) {
717 logger.Debugw(ctx, "UniVlanConfigFsm was waiting for TechProf config with this rule, aborting the outstanding config",
718 log.Fields{"device-id": oFsm.deviceID})
719 cancelPendingConfig = true
720 } else {
721 //create a new element for the removeVlanFlow slice
722 loRemoveParams = uniRemoveVlanFlowParams{
723 vlanRuleParams: storedUniFlowParams.VlanRuleParams,
724 cookie: aCookie,
725 }
726 oFsm.uniRemoveFlowsSlice = append(oFsm.uniRemoveFlowsSlice, loRemoveParams)
mpagenko01e726e2020-10-23 09:45:29 +0000727 }
mpagenko01e726e2020-10-23 09:45:29 +0000728
729 //and remove the actual element from the addVlanFlow slice
730 // oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = nil //automatically done by garbage collector
731 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
732 oFsm.numUniFlows = 0 //no more flows
733 oFsm.configuredUniFlow = 0 //no more flows configured
734 oFsm.uniVlanFlowParamsSlice = nil //reset the slice
mpagenko2418ab02020-11-12 12:58:06 +0000735 //at this point it is evident that no flow anymore refers to a still possibly active Techprofile
mpagenko535d6ef2021-02-26 13:15:34 +0000736 //request that this profile gets deleted before a new flow add is allowed (except for some aborted add)
737 if !cancelPendingConfig {
738 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, loRemoveParams.vlanRuleParams.TpID, true)
739 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000740 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - no more flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000741 "device-id": oFsm.deviceID})
742 } else {
743 oFsm.numUniFlows--
744 if oFsm.configuredUniFlow > 0 {
745 oFsm.configuredUniFlow--
746 //TODO!! might be needed to consider still outstanding configure requests ..
747 // so a flow at removal might still not be configured !?!
748 }
mpagenko2418ab02020-11-12 12:58:06 +0000749 usedTpID := storedUniFlowParams.VlanRuleParams.TpID
mpagenko01e726e2020-10-23 09:45:29 +0000750 //cut off the requested flow by slicing out this element
751 oFsm.uniVlanFlowParamsSlice = append(
752 oFsm.uniVlanFlowParamsSlice[:flow], oFsm.uniVlanFlowParamsSlice[flow+1:]...)
mpagenko2418ab02020-11-12 12:58:06 +0000753 //here we have to check, if there are still other flows referencing to the actual ProfileId
754 // before we can request that this profile gets deleted before a new flow add is allowed
mpagenkof1fc3862021-02-16 10:09:52 +0000755 // (needed to extract to function due to lint complexity)
mpagenko535d6ef2021-02-26 13:15:34 +0000756 if !cancelPendingConfig {
757 oFsm.updateTechProfileToDelete(ctx, usedTpID)
758 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000759 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow removed from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000760 "device-id": oFsm.deviceID})
761 }
762 //trigger the FSM to remove the relevant rule
mpagenko535d6ef2021-02-26 13:15:34 +0000763 if cancelPendingConfig {
764 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
mpagenkobb47bc22021-04-20 13:29:09 +0000765 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
766 // synchronous FSM 'event/state' functions may rely on this mutex
767 oFsm.mutexFlowParams.Unlock()
768 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvCancelOutstandingConfig); fsmErr != nil {
769 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
770 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
771 }
772 oFsm.mutexFlowParams.Lock()
mpagenko535d6ef2021-02-26 13:15:34 +0000773 } else {
774 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
775 logger.Debugw(ctx, "UniVlanConfigFsm rule removal request", log.Fields{
776 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
777 "tp-id": loRemoveParams.vlanRuleParams.TpID,
778 "set-Vlan": loRemoveParams.vlanRuleParams.SetVid})
779 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
mpagenkobb47bc22021-04-20 13:29:09 +0000780 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
781 // synchronous FSM 'event/state' functions may rely on this mutex
782 oFsm.mutexFlowParams.Unlock()
783 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvRemFlowConfig); fsmErr != nil {
784 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
785 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
786 }
787 oFsm.mutexFlowParams.Lock()
mpagenko535d6ef2021-02-26 13:15:34 +0000788 } // if not in the appropriate state a new entry will be automatically considered later
789 // when the configDone state is reached
790 }
mpagenko01e726e2020-10-23 09:45:29 +0000791 } else {
mpagenko01e726e2020-10-23 09:45:29 +0000792 //cut off the requested cookie by slicing out this element
793 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(
794 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[:i],
795 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[i+1:]...)
mpagenkofc4f56e2020-11-04 17:17:49 +0000796 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
mpagenkof1fc3862021-02-16 10:09:52 +0000797 kvStoreWrite = true // ensure actual data write to kvStore immediately (no FSM activity)
mpagenkofc4f56e2020-11-04 17:17:49 +0000798 // state transition notification is checked in deviceHandler
799 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000800 // success indication without the need to write to kvStore (done already below with updated data from storePersUniFlowConfig())
801 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000802 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000803 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - rule persists with still valid cookies", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000804 "device-id": oFsm.deviceID, "cookies": oFsm.uniVlanFlowParamsSlice[flow].CookieSlice})
mpagenkof1fc3862021-02-16 10:09:52 +0000805 if deletedCookie == oFsm.delayNewRuleCookie {
806 //the delayedNewCookie is the one that is currently deleted, but the rule still exist with other cookies
807 //as long as there are further cookies for this rule indicate there is still some cookie to be deleted
808 //simply use the first one
809 oFsm.delayNewRuleCookie = oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[0]
810 logger.Debugw(ctx, "UniVlanConfigFsm remaining cookie awaited for deletion before new rule add", log.Fields{
811 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
812 }
mpagenko01e726e2020-10-23 09:45:29 +0000813 }
mpagenko01e726e2020-10-23 09:45:29 +0000814 //permanently store the modified flow config for reconcile case
mpagenkofc4f56e2020-11-04 17:17:49 +0000815 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000816 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
817 &oFsm.uniVlanFlowParamsSlice, kvStoreWrite); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000818 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +0000819 return err
820 }
mpagenko01e726e2020-10-23 09:45:29 +0000821 }
mpagenkof1fc3862021-02-16 10:09:52 +0000822 break remove_loop //found the cookie - no further search for this requested cookie
mpagenko01e726e2020-10-23 09:45:29 +0000823 }
824 }
mpagenko01e726e2020-10-23 09:45:29 +0000825 } //search all flows
826 if !flowCookieMatch { //some cookie remove-request for a cookie that does not exist in the FSM data
dbainbri4d3a0dc2020-12-02 00:33:42 +0000827 logger.Warnw(ctx, "UniVlanConfigFsm flow removal - remove-cookie not found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000828 "device-id": oFsm.deviceID, "remove-cookie": aCookie})
829 // but accept the request with success as no such cookie (flow) does exist
mpagenkofc4f56e2020-11-04 17:17:49 +0000830 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
831 // state transition notification is checked in deviceHandler
832 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000833 // success indication without the need to write to kvStore (no change)
834 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000835 }
mpagenko01e726e2020-10-23 09:45:29 +0000836 return nil
837 } //unknown cookie
838
839 return nil
840}
841
mpagenkof1fc3862021-02-16 10:09:52 +0000842func (oFsm *UniVlanConfigFsm) updateTechProfileToDelete(ctx context.Context, usedTpID uint8) {
843 //here we have to check, if there are still other flows referencing to the actual ProfileId
844 // before we can request that this profile gets deleted before a new flow add is allowed
845 tpIDInOtherFlows := false
846 for _, tpUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
847 if tpUniFlowParams.VlanRuleParams.TpID == usedTpID {
848 tpIDInOtherFlows = true
849 break // search loop can be left
850 }
851 }
852 if tpIDInOtherFlows {
853 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is still used in other flows", log.Fields{
854 "device-id": oFsm.deviceID, "tp-id": usedTpID})
855 } else {
856 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is not used anymore", log.Fields{
857 "device-id": oFsm.deviceID, "tp-id": usedTpID})
858 //request that this profile gets deleted before a new flow add is allowed
859 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, usedTpID, true)
860 }
861}
862
dbainbri4d3a0dc2020-12-02 00:33:42 +0000863func (oFsm *UniVlanConfigFsm) enterConfigStarting(ctx context.Context, e *fsm.Event) {
864 logger.Debugw(ctx, "UniVlanConfigFsm start", log.Fields{"in state": e.FSM.Current(),
mpagenko01e726e2020-10-23 09:45:29 +0000865 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000866
867 // this FSM is not intended for re-start, needs always new creation for a new run
mpagenko01e726e2020-10-23 09:45:29 +0000868 // (self-destroying - compare enterDisabled())
mpagenkodff5dda2020-08-28 11:52:01 +0000869 oFsm.omciMIdsResponseReceived = make(chan bool)
mpagenkof1fc3862021-02-16 10:09:52 +0000870 oFsm.chCookieDeleted = make(chan bool)
mpagenkodff5dda2020-08-28 11:52:01 +0000871 // start go routine for processing of LockState messages
dbainbri4d3a0dc2020-12-02 00:33:42 +0000872 go oFsm.processOmciVlanMessages(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +0000873 //let the state machine run forward from here directly
874 pConfigVlanStateAFsm := oFsm.pAdaptFsm
875 if pConfigVlanStateAFsm != nil {
mpagenko9a304ea2020-12-16 15:54:01 +0000876
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000877 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
878 logger.Debugw(ctx, "reconciling - skip omci-config of vlan rule",
879 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
880 go func(a_pAFsm *AdapterFsm) {
881 _ = a_pAFsm.pFsm.Event(vlanEvSkipOmciConfig)
882 }(pConfigVlanStateAFsm)
883 return
884 }
885 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +0000886 //possibly the entry is not valid anymore based on intermediate delete requests
887 //just a basic protection ...
888 if len(oFsm.uniVlanFlowParamsSlice) == 0 {
889 oFsm.mutexFlowParams.Unlock()
890 logger.Debugw(ctx, "UniVlanConfigFsm start: no rule entry anymore available", log.Fields{
891 "device-id": oFsm.deviceID})
892 // Can't call FSM Event directly, decoupling it
893 go func(a_pAFsm *AdapterFsm) {
894 _ = a_pAFsm.pFsm.Event(vlanEvReset)
895 }(pConfigVlanStateAFsm)
896 return
897 }
mpagenko9a304ea2020-12-16 15:54:01 +0000898 //access to uniVlanFlowParamsSlice is done on first element only here per definition
899 //store the actual rule that shall be worked upon in the following transient states
900 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[0].VlanRuleParams
mpagenko9a304ea2020-12-16 15:54:01 +0000901 tpID := oFsm.actualUniVlanConfigRule.TpID
902 oFsm.TpIDWaitingFor = tpID
mpagenko551a4d42020-12-08 18:09:20 +0000903 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID))
mpagenko9a304ea2020-12-16 15:54:01 +0000904 logger.Debugw(ctx, "UniVlanConfigFsm - start with first rule", log.Fields{
905 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
906 "set-Vlan": oFsm.actualUniVlanConfigRule.SetVid, "tp-id": tpID, "ProfDone": loTechProfDone})
mpagenko551a4d42020-12-08 18:09:20 +0000907 //cmp also usage in EVTOCDE create in omci_cc
908 oFsm.evtocdID = macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo)
mpagenko535d6ef2021-02-26 13:15:34 +0000909 oFsm.mutexFlowParams.Unlock()
mpagenko9a304ea2020-12-16 15:54:01 +0000910 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +0000911 go func(aPAFsm *AdapterFsm, aTechProfDone bool) {
912 if aPAFsm != nil && aPAFsm.pFsm != nil {
913 if aTechProfDone {
mpagenkodff5dda2020-08-28 11:52:01 +0000914 // let the vlan processing begin
mpagenko551a4d42020-12-08 18:09:20 +0000915 _ = aPAFsm.pFsm.Event(vlanEvStartConfig)
mpagenkodff5dda2020-08-28 11:52:01 +0000916 } else {
917 // set to waiting for Techprofile
mpagenko551a4d42020-12-08 18:09:20 +0000918 _ = aPAFsm.pFsm.Event(vlanEvWaitTechProf)
mpagenkodff5dda2020-08-28 11:52:01 +0000919 }
920 }
mpagenko551a4d42020-12-08 18:09:20 +0000921 }(pConfigVlanStateAFsm, loTechProfDone)
922 } else {
923 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
924 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
925 //should never happen, else: recovery would be needed from outside the FSM
926 return
mpagenkodff5dda2020-08-28 11:52:01 +0000927 }
928}
929
dbainbri4d3a0dc2020-12-02 00:33:42 +0000930func (oFsm *UniVlanConfigFsm) enterConfigVtfd(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000931 //mutex protection is required for possible concurrent access to FSM members
932 oFsm.mutexFlowParams.Lock()
mpagenko551a4d42020-12-08 18:09:20 +0000933 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
mpagenko9a304ea2020-12-16 15:54:01 +0000934 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +0000935 // meaning transparent setup - no specific VTFD setting required
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000936 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000937 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000938 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000939 // let the FSM proceed ... (from within this state all internal pointers may be expected to be correct)
mpagenkodff5dda2020-08-28 11:52:01 +0000940 pConfigVlanStateAFsm := oFsm.pAdaptFsm
mpagenko9a304ea2020-12-16 15:54:01 +0000941 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +0000942 go func(a_pAFsm *AdapterFsm) {
Himani Chawla4d908332020-08-31 12:30:20 +0530943 _ = a_pAFsm.pFsm.Event(vlanEvRxConfigVtfd)
mpagenkodff5dda2020-08-28 11:52:01 +0000944 }(pConfigVlanStateAFsm)
945 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300946 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
947 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -0700948 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(oFsm.actualUniVlanConfigRule.TpID))
dbainbri4d3a0dc2020-12-02 00:33:42 +0000949 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300950 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -0700951 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
952 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": oFsm.actualUniVlanConfigRule.TpID})
mpagenko01e726e2020-10-23 09:45:29 +0000953 // setVid is assumed to be masked already by the caller to 12 bit
mpagenko9a304ea2020-12-16 15:54:01 +0000954 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000955 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000956 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000957 vtfdFilterList[0] = oFsm.vlanFilterList[0]
958 oFsm.numVlanFilterEntries = 1
mpagenkodff5dda2020-08-28 11:52:01 +0000959 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300960 EntityID: vtfdID,
mpagenkodff5dda2020-08-28 11:52:01 +0000961 Attributes: me.AttributeValueMap{
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000962 "VlanFilterList": vtfdFilterList, //omci lib wants a slice for serialization
963 "ForwardOperation": uint8(0x10), //VID investigation
964 "NumberOfEntries": oFsm.numVlanFilterEntries,
mpagenkodff5dda2020-08-28 11:52:01 +0000965 },
966 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000967 logger.Debugw(ctx, "UniVlanConfigFsm sendcreate VTFD", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000968 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000969 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300970 meInstance, err := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +0000971 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300972 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000973 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300974 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
975 log.Fields{"device-id": oFsm.deviceID})
976 pConfigVlanStateAFsm := oFsm.pAdaptFsm
977 if pConfigVlanStateAFsm != nil {
978 go func(a_pAFsm *AdapterFsm) {
979 _ = a_pAFsm.pFsm.Event(vlanEvReset)
980 }(pConfigVlanStateAFsm)
981 }
982 return
983 }
mpagenkodff5dda2020-08-28 11:52:01 +0000984 //accept also nil as (error) return value for writing to LastTx
985 // - this avoids misinterpretation of new received OMCI messages
986 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
987 // send shall return (dual format) error code that can be used here for immediate error treatment
988 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +0000989 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000990 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +0000991 }
992}
993
dbainbri4d3a0dc2020-12-02 00:33:42 +0000994func (oFsm *UniVlanConfigFsm) enterConfigEvtocd(ctx context.Context, e *fsm.Event) {
995 logger.Debugw(ctx, "UniVlanConfigFsm - start config EVTOCD loop", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000996 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +0000997 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300998 go func() {
mpagenko9a304ea2020-12-16 15:54:01 +0000999 //using the first element in the slice because it's the first flow per definition here
1000 errEvto := oFsm.performConfigEvtocdEntries(ctx, 0)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001001 //This is correct passing scenario
1002 if errEvto == nil {
mpagenko9a304ea2020-12-16 15:54:01 +00001003 tpID := oFsm.actualUniVlanConfigRule.TpID
1004 vlanID := oFsm.actualUniVlanConfigRule.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +00001005 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
1006 logger.Infow(ctx, "Setting multicast MEs, with first flow", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001007 "techProfile": tpID, "gemPort": gemPort, "vlanID": vlanID, "configuredUniFlow": oFsm.configuredUniFlow})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001008 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001009 vlanID)
1010 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001011 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001012 log.Fields{"device-id": oFsm.deviceID})
1013 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1014 }
1015 }
1016 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
1017 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
1018 }
1019 }()
mpagenkodff5dda2020-08-28 11:52:01 +00001020}
1021
dbainbri4d3a0dc2020-12-02 00:33:42 +00001022func (oFsm *UniVlanConfigFsm) enterVlanConfigDone(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001023
mpagenko9a304ea2020-12-16 15:54:01 +00001024 oFsm.mutexFlowParams.RLock()
1025 defer oFsm.mutexFlowParams.RUnlock()
1026
mpagenkof1fc3862021-02-16 10:09:52 +00001027 logger.Infow(ctx, "UniVlanConfigFsm config done - checking on more flows", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00001028 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1029 "overall-uni-rules": oFsm.numUniFlows, "configured-uni-rules": oFsm.configuredUniFlow})
1030 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1031 if pConfigVlanStateAFsm == nil {
mpagenko551a4d42020-12-08 18:09:20 +00001032 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1033 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1034 //should never happen, else: recovery would be needed from outside the FSM
1035 return
1036 }
1037 pConfigVlanStateBaseFsm := pConfigVlanStateAFsm.pFsm
mpagenko01e726e2020-10-23 09:45:29 +00001038 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1039 //some further flows are to be removed, removal always starts with the first element
mpagenko9a304ea2020-12-16 15:54:01 +00001040 logger.Debugw(ctx, "UniVlanConfigFsm rule removal from ConfigDone", log.Fields{
1041 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
1042 "tp-id": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.TpID,
1043 "set-Vlan": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.SetVid})
1044 // Can't call FSM Event directly, decoupling it
mpagenko01e726e2020-10-23 09:45:29 +00001045 go func(a_pBaseFsm *fsm.FSM) {
1046 _ = a_pBaseFsm.Event(vlanEvRemFlowConfig)
1047 }(pConfigVlanStateBaseFsm)
1048 return
1049 }
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001050 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
1051 oFsm.configuredUniFlow = oFsm.numUniFlows
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001052 if !oFsm.pDeviceHandler.isReconcilingFlows() {
1053 logger.Debugw(ctx, "reconciling - flow processing finished", log.Fields{"device-id": oFsm.deviceID})
1054 oFsm.pDeviceHandler.chReconcilingFlowsFinished <- true
1055 }
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001056 logger.Debugw(ctx, "reconciling - skip enterVlanConfigDone processing",
1057 log.Fields{"numUniFlows": oFsm.numUniFlows, "configuredUniFlow": oFsm.configuredUniFlow, "device-id": oFsm.deviceID})
1058 return
1059 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001060 if oFsm.numUniFlows > oFsm.configuredUniFlow {
mpagenko551a4d42020-12-08 18:09:20 +00001061 if oFsm.configuredUniFlow == 0 {
mpagenko551a4d42020-12-08 18:09:20 +00001062 // this is a restart with a complete new flow, we can re-use the initial flow config control
1063 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenko9a304ea2020-12-16 15:54:01 +00001064 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001065 go func(a_pBaseFsm *fsm.FSM) {
1066 _ = a_pBaseFsm.Event(vlanEvRenew)
1067 }(pConfigVlanStateBaseFsm)
1068 return
1069 }
1070
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001071 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001072 //store the actual rule that shall be worked upon in the following transient states
1073 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +00001074 //tpId of the next rule to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001075 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko551a4d42020-12-08 18:09:20 +00001076 oFsm.TpIDWaitingFor = tpID
mpagenko551a4d42020-12-08 18:09:20 +00001077 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, tpID)
mpagenko9a304ea2020-12-16 15:54:01 +00001078 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request", log.Fields{
1079 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
1080 "set-Vlan": oFsm.actualUniVlanConfigRule.SetVid, "tp-id": tpID, "ProfDone": loTechProfDone})
1081 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001082 go func(aPBaseFsm *fsm.FSM, aTechProfDone bool) {
1083 if aTechProfDone {
1084 // let the vlan processing continue with next rule
1085 _ = aPBaseFsm.Event(vlanEvIncrFlowConfig)
1086 } else {
1087 // set to waiting for Techprofile
1088 _ = aPBaseFsm.Event(vlanEvWaitTPIncr)
1089 }
1090 }(pConfigVlanStateBaseFsm, loTechProfDone)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001091 return
1092 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001093 logger.Debugw(ctx, "UniVlanConfigFsm - VLAN config done: send dh event notification", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001094 "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001095 // it might appear that some flows are requested also after 'flowPushed' event has been generated ...
1096 // state transition notification is checked in deviceHandler
mpagenko551a4d42020-12-08 18:09:20 +00001097 // note: 'flowPushed' event is only generated if all 'pending' rules are configured
mpagenkodff5dda2020-08-28 11:52:01 +00001098 if oFsm.pDeviceHandler != nil {
mpagenkofc4f56e2020-11-04 17:17:49 +00001099 //making use of the add->remove successor enum assumption/definition
dbainbri4d3a0dc2020-12-02 00:33:42 +00001100 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(uint8(oFsm.requestEvent)+oFsm.requestEventOffset))
mpagenkodff5dda2020-08-28 11:52:01 +00001101 }
1102}
1103
dbainbri4d3a0dc2020-12-02 00:33:42 +00001104func (oFsm *UniVlanConfigFsm) enterConfigIncrFlow(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001105
1106 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
1107 logger.Debugw(ctx, "reconciling - skip further processing for incremental flow",
1108 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
1109 go func(a_pBaseFsm *fsm.FSM) {
1110 _ = a_pBaseFsm.Event(vlanEvSkipIncFlowConfig)
1111 }(oFsm.pAdaptFsm.pFsm)
1112 return
1113 }
mpagenko15ff4a52021-03-02 10:09:20 +00001114 oFsm.mutexFlowParams.Lock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001115 logger.Debugw(ctx, "UniVlanConfigFsm - start config further incremental flow", log.Fields{
Girish Gowdra041dcb32020-11-16 16:54:30 -08001116 "in state": e.FSM.Current(), "recent flow-number": oFsm.configuredUniFlow,
mpagenko01e726e2020-10-23 09:45:29 +00001117 "device-id": oFsm.deviceID})
mpagenko551a4d42020-12-08 18:09:20 +00001118 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001119
mpagenko9a304ea2020-12-16 15:54:01 +00001120 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001121 // meaning transparent setup - no specific VTFD setting required
1122 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001123 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001124 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001125 } else {
mpagenkocf48e452021-04-23 09:23:00 +00001126 //TODO!!!: it was not really intended to keep this enter* FSM method waiting on OMCI response (preventing other state transitions)
1127 // so it would be conceptually better to wait for the response in background like for the other multi-entity processing
1128 // but as the OMCI sequence must be ensured, a separate new state would be required - perhaps later
1129 // 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 +00001130 if oFsm.numVlanFilterEntries == 0 {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001131 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1132 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07001133 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(oFsm.actualUniVlanConfigRule.TpID))
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001134 //no VTFD yet created
dbainbri4d3a0dc2020-12-02 00:33:42 +00001135 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001136 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001137 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1138 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": oFsm.actualUniVlanConfigRule.TpID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001139 // 'SetVid' below is assumed to be masked already by the caller to 12 bit
mpagenko9a304ea2020-12-16 15:54:01 +00001140 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001141
mpagenko01e726e2020-10-23 09:45:29 +00001142 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001143 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1144 oFsm.numVlanFilterEntries = 1
1145 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001146 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001147 Attributes: me.AttributeValueMap{
1148 "VlanFilterList": vtfdFilterList,
1149 "ForwardOperation": uint8(0x10), //VID investigation
1150 "NumberOfEntries": oFsm.numVlanFilterEntries,
1151 },
1152 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001153 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001154 meInstance, err := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001155 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001156 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001157 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001158 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1159 log.Fields{"device-id": oFsm.deviceID})
1160 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1161 if pConfigVlanStateAFsm != nil {
1162 go func(a_pAFsm *AdapterFsm) {
1163 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1164 }(pConfigVlanStateAFsm)
1165 }
1166 return
1167 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001168 //accept also nil as (error) return value for writing to LastTx
1169 // - this avoids misinterpretation of new received OMCI messages
1170 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1171 // send shall return (dual format) error code that can be used here for immediate error treatment
1172 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001173 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001174 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001175 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001176 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1177 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07001178 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(oFsm.actualUniVlanConfigRule.TpID))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001179
dbainbri4d3a0dc2020-12-02 00:33:42 +00001180 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001181 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001182 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1183 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": oFsm.actualUniVlanConfigRule.TpID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001184 // setVid is assumed to be masked already by the caller to 12 bit
1185 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] =
mpagenko9a304ea2020-12-16 15:54:01 +00001186 uint16(oFsm.actualUniVlanConfigRule.SetVid)
mpagenko01e726e2020-10-23 09:45:29 +00001187 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001188
1189 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
1190 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
1191 // new vlan associated with a different TP.
mpagenko9a304ea2020-12-16 15:54:01 +00001192 vtfdFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001193
1194 oFsm.numVlanFilterEntries++
1195 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001196 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001197 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001198 "VlanFilterList": vtfdFilterList,
1199 "ForwardOperation": uint8(0x10), //VID investigation
1200 "NumberOfEntries": oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001201 },
1202 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001203 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001204 meInstance, err := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001205 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001206 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001207 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001208 logger.Errorw(ctx, "UniVlanFsm create Vlan Tagging Filter ME result error",
1209 log.Fields{"device-id": oFsm.deviceID, "Error": err})
1210 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1211 return
1212 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001213 //accept also nil as (error) return value for writing to LastTx
1214 // - this avoids misinterpretation of new received OMCI messages
1215 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1216 // send shall return (dual format) error code that can be used here for immediate error treatment
1217 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001218 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001219 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001220 }
mpagenko15ff4a52021-03-02 10:09:20 +00001221 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001222 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001223 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001224 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001225 logger.Errorw(ctx, "VTFD create/set failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001226 log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001227 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001228 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001229 go func(a_pBaseFsm *fsm.FSM) {
1230 _ = a_pBaseFsm.Event(vlanEvReset)
1231 }(pConfigVlanStateBaseFsm)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001232 return
1233 }
1234 }
mpagenko15ff4a52021-03-02 10:09:20 +00001235 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001236 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
mpagenko15ff4a52021-03-02 10:09:20 +00001237 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001238 go func() {
mpagenko15ff4a52021-03-02 10:09:20 +00001239 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001240 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko15ff4a52021-03-02 10:09:20 +00001241 configuredUniFlow := oFsm.configuredUniFlow
1242 oFsm.mutexFlowParams.RUnlock()
1243 errEvto := oFsm.performConfigEvtocdEntries(ctx, configuredUniFlow)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001244 //This is correct passing scenario
1245 if errEvto == nil {
1246 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
dbainbri4d3a0dc2020-12-02 00:33:42 +00001247 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
mpagenko15ff4a52021-03-02 10:09:20 +00001248 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001249 vlanID := oFsm.actualUniVlanConfigRule.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +00001250 logger.Infow(ctx, "Setting multicast MEs for additional flows", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001251 "techProfile": tpID, "gemPort": gemPort,
1252 "vlanID": vlanID, "configuredUniFlow": oFsm.configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +00001253 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001254 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001255 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001256 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001257 log.Fields{"device-id": oFsm.deviceID})
1258 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1259 }
1260 }
1261 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
1262 }
1263 }()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001264}
1265
dbainbri4d3a0dc2020-12-02 00:33:42 +00001266func (oFsm *UniVlanConfigFsm) enterRemoveFlow(ctx context.Context, e *fsm.Event) {
mpagenko551a4d42020-12-08 18:09:20 +00001267 oFsm.mutexFlowParams.RLock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001268 logger.Debugw(ctx, "UniVlanConfigFsm - start removing the top remove-flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001269 "in state": e.FSM.Current(), "with last cookie": oFsm.uniRemoveFlowsSlice[0].cookie,
1270 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001271
mpagenkofc4f56e2020-11-04 17:17:49 +00001272 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001273 loAllowSpecificOmciConfig := oFsm.pDeviceHandler.isReadyForOmciConfig()
mpagenko01e726e2020-10-23 09:45:29 +00001274 loVlanEntryClear := uint8(0)
1275 loVlanEntryRmPos := uint8(0x80) //with indication 'invalid' in bit 7
1276 //shallow copy is sufficient as no reference variables are used within struct
1277 loRuleParams := oFsm.uniRemoveFlowsSlice[0].vlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +00001278 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001279 logger.Debugw(ctx, "UniVlanConfigFsm - remove-flow parameters are", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001280 "match vid": loRuleParams.MatchVid, "match Pcp": loRuleParams.MatchPcp,
1281 "set vid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
1282 "device-id": oFsm.deviceID})
1283
1284 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
1285 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001286 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD removal required for transparent flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001287 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1288 } else {
1289 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization and 're-copy'
1290 if oFsm.numVlanFilterEntries == 1 {
Mahir Gunyel6781f962021-05-16 23:30:08 -07001291 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001292 //only one active VLAN entry (hopefully the SetVID we want to remove - should be, but not verified ..)
1293 // so we can just delete the VTFD entry
dbainbri4d3a0dc2020-12-02 00:33:42 +00001294 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD delete (no more vlan filters)",
Mahir Gunyel6781f962021-05-16 23:30:08 -07001295 log.Fields{"current vlan list": oFsm.vlanFilterList, "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
1296 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1297 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": loRuleParams.TpID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001298 loVlanEntryClear = 1 //full VlanFilter clear request
1299 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001300 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001301 meInstance, err := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001302 oFsm.pAdaptFsm.commChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001303 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001304 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001305 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1306 log.Fields{"device-id": oFsm.deviceID, "Error": err})
1307 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1308 return
1309 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001310 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001311 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001312 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001313 logger.Debugw(ctx, "UniVlanConfigFsm delete VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001314 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.getDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +00001315 }
mpagenko01e726e2020-10-23 09:45:29 +00001316 } else {
1317 //many VTFD already should exists - find and remove the one concerned by the actual remove rule
1318 // by updating the VTFD per set command with new valid list
dbainbri4d3a0dc2020-12-02 00:33:42 +00001319 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD removal of requested VLAN from the list on OMCI",
mpagenko01e726e2020-10-23 09:45:29 +00001320 log.Fields{"current vlan list": oFsm.vlanFilterList,
1321 "set-vlan": loRuleParams.SetVid, "device-id": oFsm.deviceID})
1322 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1323 if loRuleParams.SetVid == uint32(oFsm.vlanFilterList[i]) {
1324 loVlanEntryRmPos = i
1325 break //abort search
1326 }
1327 }
1328 if loVlanEntryRmPos < cVtfdTableSize {
Mahir Gunyel6781f962021-05-16 23:30:08 -07001329 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001330 //valid entry was found - to be eclipsed
1331 loVlanEntryClear = 2 //VlanFilter remove request for a specific entry
1332 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1333 if i < loVlanEntryRmPos {
1334 vtfdFilterList[i] = oFsm.vlanFilterList[i] //copy original
1335 } else if i < (cVtfdTableSize - 1) {
1336 vtfdFilterList[i] = oFsm.vlanFilterList[i+1] //copy successor (including 0 elements)
1337 } else {
1338 vtfdFilterList[i] = 0 //set last byte if needed
1339 }
1340 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001341 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001342 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001343 "new vlan list": vtfdFilterList, "device-id": oFsm.deviceID,
1344 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": loRuleParams.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001345
mpagenkofc4f56e2020-11-04 17:17:49 +00001346 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001347 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001348 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001349 meInstance, err := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001350 oFsm.pAdaptFsm.commChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001351 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001352 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001353 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1354 log.Fields{"device-id": oFsm.deviceID, "Error": err})
1355 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1356 return
1357 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001358 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001359 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001360 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001361 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001362 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.getDeviceReasonString()})
mpagenko01e726e2020-10-23 09:45:29 +00001363 }
mpagenko01e726e2020-10-23 09:45:29 +00001364 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001365 logger.Warnw(ctx, "UniVlanConfigFsm: requested VLAN for removal not found in list - ignore and continue (no VTFD set)",
mpagenko01e726e2020-10-23 09:45:29 +00001366 log.Fields{"device-id": oFsm.deviceID})
1367 }
1368 }
1369 if loVlanEntryClear > 0 {
mpagenkofc4f56e2020-11-04 17:17:49 +00001370 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
1371 //waiting on response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001372 err := oFsm.waitforOmciResponse(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001373 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001374 logger.Errorw(ctx, "VTFD delete/reset failed, aborting VlanConfig FSM!",
mpagenkofc4f56e2020-11-04 17:17:49 +00001375 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001376 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001377 go func(a_pBaseFsm *fsm.FSM) {
1378 _ = a_pBaseFsm.Event(vlanEvReset)
1379 }(pConfigVlanStateBaseFsm)
1380 return
1381 }
mpagenko01e726e2020-10-23 09:45:29 +00001382 }
1383
mpagenko15ff4a52021-03-02 10:09:20 +00001384 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00001385 if loVlanEntryClear == 1 {
1386 oFsm.vlanFilterList[0] = 0 //first entry is the only that can contain the previous only-one element
1387 oFsm.numVlanFilterEntries = 0
1388 } else if loVlanEntryClear == 2 {
1389 // new VlanFilterList should be one entry smaller now - copy from last configured entry
1390 // this loop now includes the 0 element on previous last valid entry
1391 for i := uint8(0); i <= oFsm.numVlanFilterEntries; i++ {
1392 oFsm.vlanFilterList[i] = vtfdFilterList[i]
1393 }
1394 oFsm.numVlanFilterEntries--
1395 }
mpagenko15ff4a52021-03-02 10:09:20 +00001396 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001397 }
1398 }
1399
mpagenkofc4f56e2020-11-04 17:17:49 +00001400 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001401 go oFsm.removeEvtocdEntries(ctx, loRuleParams)
mpagenkofc4f56e2020-11-04 17:17:49 +00001402 } else {
1403 // OMCI processing is not done, expectation is to have the ONU in some basic config state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001404 logger.Debugw(ctx, "UniVlanConfigFsm remove EVTOCD OMCI handling skipped based on device state", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +00001405 "device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001406 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001407 go func(a_pBaseFsm *fsm.FSM) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001408 _ = a_pBaseFsm.Event(vlanEvRemFlowDone, loRuleParams.TpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001409 }(pConfigVlanStateBaseFsm)
1410 }
mpagenkodff5dda2020-08-28 11:52:01 +00001411}
1412
dbainbri4d3a0dc2020-12-02 00:33:42 +00001413func (oFsm *UniVlanConfigFsm) enterVlanCleanupDone(ctx context.Context, e *fsm.Event) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001414 var tpID uint8
1415 // Extract the tpID
1416 if len(e.Args) > 0 {
1417 tpID = e.Args[0].(uint8)
1418 logger.Debugw(ctx, "UniVlanConfigFsm - flow removed for tp id", log.Fields{"device-id": oFsm.deviceID, "tpID": e.Args[0].(uint8)})
1419 } else {
1420 logger.Warnw(ctx, "UniVlanConfigFsm - tp id not available", log.Fields{"device-id": oFsm.deviceID})
1421 }
mpagenko01e726e2020-10-23 09:45:29 +00001422 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001423 deletedCookie := oFsm.uniRemoveFlowsSlice[0].cookie
1424 logger.Debugw(ctx, "UniVlanConfigFsm - removing the removal data", log.Fields{
1425 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1426 "removed cookie": deletedCookie, "waitForDeleteCookie": oFsm.delayNewRuleCookie})
1427
mpagenko01e726e2020-10-23 09:45:29 +00001428 if len(oFsm.uniRemoveFlowsSlice) <= 1 {
1429 oFsm.uniRemoveFlowsSlice = nil //reset the slice
dbainbri4d3a0dc2020-12-02 00:33:42 +00001430 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - last remove-flow deleted", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001431 "device-id": oFsm.deviceID})
1432 } else {
1433 //cut off the actual flow by slicing out the first element
1434 oFsm.uniRemoveFlowsSlice = append(
1435 oFsm.uniRemoveFlowsSlice[:0],
1436 oFsm.uniRemoveFlowsSlice[1:]...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001437 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow deleted from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001438 "device-id": oFsm.deviceID})
1439 }
1440 oFsm.mutexFlowParams.Unlock()
1441
mpagenkof1fc3862021-02-16 10:09:52 +00001442 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
mpagenko01e726e2020-10-23 09:45:29 +00001443 //return to the basic config verification state
mpagenkodff5dda2020-08-28 11:52:01 +00001444 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1445 if pConfigVlanStateAFsm != nil {
mpagenko9a304ea2020-12-16 15:54:01 +00001446 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +00001447 go func(a_pAFsm *AdapterFsm) {
1448 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001449 _ = a_pAFsm.pFsm.Event(vlanEvFlowDataRemoved)
mpagenkodff5dda2020-08-28 11:52:01 +00001450 }
1451 }(pConfigVlanStateAFsm)
1452 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001453
mpagenkobb47bc22021-04-20 13:29:09 +00001454 oFsm.mutexFlowParams.Lock()
Girish Gowdra26a40922021-01-29 17:14:34 -08001455 noOfFlowRem := len(oFsm.uniRemoveFlowsSlice)
mpagenkof1fc3862021-02-16 10:09:52 +00001456 if deletedCookie == oFsm.delayNewRuleCookie {
1457 // flush the channel CookieDeleted to ensure it is not lingering from some previous (aborted) activity
1458 select {
1459 case <-oFsm.chCookieDeleted:
1460 logger.Debug(ctx, "flushed CookieDeleted")
1461 default:
1462 }
1463 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue
1464 }
mpagenkobb47bc22021-04-20 13:29:09 +00001465 // If all pending flow-removes are completed and TP ID is valid go on processing any pending TP delete
1466 if oFsm.signalOnFlowDelete && noOfFlowRem == 0 && tpID > 0 {
1467 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 -08001468 // If we are here then all flows are removed.
mpagenkobb47bc22021-04-20 13:29:09 +00001469 if len(oFsm.flowDeleteChannel) == 0 { //channel not yet in use
1470 oFsm.flowDeleteChannel <- true
1471 oFsm.signalOnFlowDelete = false
1472 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001473 }
mpagenkobb47bc22021-04-20 13:29:09 +00001474 oFsm.mutexFlowParams.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001475}
1476
dbainbri4d3a0dc2020-12-02 00:33:42 +00001477func (oFsm *UniVlanConfigFsm) enterResetting(ctx context.Context, e *fsm.Event) {
1478 logger.Debugw(ctx, "UniVlanConfigFsm resetting", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001479
1480 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1481 if pConfigVlanStateAFsm != nil {
1482 // abort running message processing
1483 fsmAbortMsg := Message{
1484 Type: TestMsg,
1485 Data: TestMessage{
1486 TestMessageVal: AbortMessageProcessing,
1487 },
1488 }
1489 pConfigVlanStateAFsm.commChan <- fsmAbortMsg
1490
mpagenko9a304ea2020-12-16 15:54:01 +00001491 //try to restart the FSM to 'disabled'
1492 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +00001493 go func(a_pAFsm *AdapterFsm) {
1494 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301495 _ = a_pAFsm.pFsm.Event(vlanEvRestart)
mpagenkodff5dda2020-08-28 11:52:01 +00001496 }
1497 }(pConfigVlanStateAFsm)
1498 }
1499}
1500
dbainbri4d3a0dc2020-12-02 00:33:42 +00001501func (oFsm *UniVlanConfigFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
1502 logger.Debugw(ctx, "UniVlanConfigFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001503 oFsm.mutexPLastTxMeInstance.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00001504 oFsm.pLastTxMeInstance = nil
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001505 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001506 if oFsm.pDeviceHandler != nil {
mpagenko2418ab02020-11-12 12:58:06 +00001507 //TODO: to clarify with improved error treatment for VlanConfigFsm (timeout,reception) errors
1508 // current code removes the complete FSM including all flow/rule configuration done so far
1509 // this might be a bit to much, it would require fully new flow config from rwCore (at least on OnuDown/up)
1510 // maybe a more sophisticated approach is possible without clearing the data
mpagenko9a304ea2020-12-16 15:54:01 +00001511 oFsm.mutexFlowParams.RLock()
mpagenko2418ab02020-11-12 12:58:06 +00001512 if oFsm.clearPersistency {
1513 //permanently remove possibly stored persistent data
1514 if len(oFsm.uniVlanFlowParamsSlice) > 0 {
1515 var emptySlice = make([]uniVlanFlowParams, 0)
mpagenkof1fc3862021-02-16 10:09:52 +00001516 _ = oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID, &emptySlice, true) //ignore errors
mpagenko2418ab02020-11-12 12:58:06 +00001517 }
1518 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001519 logger.Debugw(ctx, "UniVlanConfigFsm persistency data not cleared", log.Fields{"device-id": oFsm.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001520 }
mpagenkof1fc3862021-02-16 10:09:52 +00001521 if oFsm.delayNewRuleCookie != 0 {
1522 // looks like the waiting AddFlow is stuck
1523 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue/treminate
1524 }
mpagenko9a304ea2020-12-16 15:54:01 +00001525 oFsm.mutexFlowParams.RUnlock()
mpagenko2418ab02020-11-12 12:58:06 +00001526 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001527 go oFsm.pDeviceHandler.RemoveVlanFilterFsm(ctx, oFsm.pOnuUniPort)
mpagenkodff5dda2020-08-28 11:52:01 +00001528 }
1529}
1530
dbainbri4d3a0dc2020-12-02 00:33:42 +00001531func (oFsm *UniVlanConfigFsm) processOmciVlanMessages(ctx context.Context) { //ctx context.Context?
1532 logger.Debugw(ctx, "Start UniVlanConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001533loop:
1534 for {
mpagenkodff5dda2020-08-28 11:52:01 +00001535 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00001536 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001537 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +05301538 message, ok := <-oFsm.pAdaptFsm.commChan
1539 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001540 logger.Info(ctx, "UniVlanConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301541 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
1542 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1543 break loop
1544 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001545 logger.Debugw(ctx, "UniVlanConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301546
1547 switch message.Type {
1548 case TestMsg:
1549 msg, _ := message.Data.(TestMessage)
1550 if msg.TestMessageVal == AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001551 logger.Infow(ctx, "UniVlanConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001552 break loop
1553 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001554 logger.Warnw(ctx, "UniVlanConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Himani Chawla4d908332020-08-31 12:30:20 +05301555 case OMCI:
1556 msg, _ := message.Data.(OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001557 oFsm.handleOmciVlanConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301558 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001559 logger.Warn(ctx, "UniVlanConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301560 "message.Type": message.Type})
mpagenkodff5dda2020-08-28 11:52:01 +00001561 }
1562 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001563 logger.Infow(ctx, "End UniVlanConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001564}
1565
dbainbri4d3a0dc2020-12-02 00:33:42 +00001566func (oFsm *UniVlanConfigFsm) handleOmciVlanConfigMessage(ctx context.Context, msg OmciMessage) {
1567 logger.Debugw(ctx, "Rx OMCI UniVlanConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001568 "msgType": msg.OmciMsg.MessageType})
1569
1570 switch msg.OmciMsg.MessageType {
1571 case omci.CreateResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001572 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001573 if err := oFsm.handleOmciCreateResponseMessage(ctx, msg.OmciPacket); err != nil {
1574 logger.Warnw(ctx, "CreateResponse handling aborted", log.Fields{"err": err})
mpagenkodff5dda2020-08-28 11:52:01 +00001575 return
1576 }
mpagenkodff5dda2020-08-28 11:52:01 +00001577 } //CreateResponseType
1578 case omci.SetResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001579 { //leave that here as direct code as most often used
mpagenkodff5dda2020-08-28 11:52:01 +00001580 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1581 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001582 logger.Errorw(ctx, "Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001583 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001584 return
1585 }
1586 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1587 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001588 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001589 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001590 return
1591 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001592 logger.Debugw(ctx, "UniVlanConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkodff5dda2020-08-28 11:52:01 +00001593 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001594 logger.Errorw(ctx, "UniVlanConfigFsm Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001595 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
mpagenkodff5dda2020-08-28 11:52:01 +00001596 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1597 return
1598 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001599 oFsm.mutexPLastTxMeInstance.RLock()
1600 if oFsm.pLastTxMeInstance != nil {
1601 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1602 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1603 switch oFsm.pLastTxMeInstance.GetName() {
1604 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "MulticastOperationsProfile":
1605 { // let the MultiEntity config proceed by stopping the wait function
1606 oFsm.mutexPLastTxMeInstance.RUnlock()
1607 oFsm.omciMIdsResponseReceived <- true
1608 return
1609 }
1610 default:
1611 {
1612 logger.Warnw(ctx, "Unsupported ME name received!",
1613 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1614 }
mpagenkodff5dda2020-08-28 11:52:01 +00001615 }
1616 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001617 } else {
1618 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001619 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001620 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001621 } //SetResponseType
mpagenko01e726e2020-10-23 09:45:29 +00001622 case omci.DeleteResponseType:
1623 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001624 if err := oFsm.handleOmciDeleteResponseMessage(ctx, msg.OmciPacket); err != nil {
1625 logger.Warnw(ctx, "DeleteResponse handling aborted", log.Fields{"err": err})
mpagenko01e726e2020-10-23 09:45:29 +00001626 return
1627 }
1628 } //DeleteResponseType
mpagenkodff5dda2020-08-28 11:52:01 +00001629 default:
1630 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001631 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00001632 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001633 return
1634 }
1635 }
1636}
1637
dbainbri4d3a0dc2020-12-02 00:33:42 +00001638func (oFsm *UniVlanConfigFsm) handleOmciCreateResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00001639 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeCreateResponse)
1640 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001641 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001642 log.Fields{"device-id": oFsm.deviceID})
1643 return fmt.Errorf("omci msg layer could not be detected for CreateResponse for device-id %x",
1644 oFsm.deviceID)
1645 }
1646 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
1647 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001648 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001649 log.Fields{"device-id": oFsm.deviceID})
1650 return fmt.Errorf("omci msg layer could not be assigned for CreateResponse for device-id %x",
1651 oFsm.deviceID)
1652 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001653 logger.Debugw(ctx, "UniVlanConfigFsm CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001654 if msgObj.Result != me.Success && msgObj.Result != me.InstanceExists {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001655 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"device-id": oFsm.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00001656 "Error": msgObj.Result})
1657 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1658 return fmt.Errorf("omci CreateResponse Error for device-id %x",
1659 oFsm.deviceID)
1660 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001661 oFsm.mutexPLastTxMeInstance.RLock()
1662 if oFsm.pLastTxMeInstance != nil {
1663 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1664 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1665 // to satisfy StaticCodeAnalysis I had to move the small processing into a separate method :-(
1666 switch oFsm.pLastTxMeInstance.GetName() {
1667 case "VlanTaggingFilterData", "MulticastOperationsProfile",
1668 "MulticastSubscriberConfigInfo", "MacBridgePortConfigurationData",
1669 "ExtendedVlanTaggingOperationConfigurationData":
1670 {
1671 oFsm.mutexPLastTxMeInstance.RUnlock()
1672 if oFsm.pAdaptFsm.pFsm.Current() == vlanStConfigVtfd {
1673 // Only if CreateResponse is received from first flow entry - let the FSM proceed ...
1674 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigVtfd)
1675 } else { // let the MultiEntity config proceed by stopping the wait function
1676 oFsm.omciMIdsResponseReceived <- true
1677 }
1678 return nil
1679 }
1680 default:
1681 {
1682 logger.Warnw(ctx, "Unsupported ME name received!",
1683 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001684 }
1685 }
1686 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001687 } else {
1688 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001689 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001690 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00001691 return nil
1692}
1693
dbainbri4d3a0dc2020-12-02 00:33:42 +00001694func (oFsm *UniVlanConfigFsm) handleOmciDeleteResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00001695 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeDeleteResponse)
1696 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001697 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001698 log.Fields{"device-id": oFsm.deviceID})
1699 return fmt.Errorf("omci msg layer could not be detected for DeleteResponse for device-id %x",
1700 oFsm.deviceID)
1701 }
1702 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
1703 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001704 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001705 log.Fields{"device-id": oFsm.deviceID})
1706 return fmt.Errorf("omci msg layer could not be assigned for DeleteResponse for device-id %x",
1707 oFsm.deviceID)
1708 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001709 logger.Debugw(ctx, "UniVlanConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko01e726e2020-10-23 09:45:29 +00001710 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001711 logger.Errorw(ctx, "UniVlanConfigFsm - Omci DeleteResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001712 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1713 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1714 return fmt.Errorf("omci DeleteResponse Error for device-id %x",
1715 oFsm.deviceID)
1716 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001717 oFsm.mutexPLastTxMeInstance.RLock()
1718 if oFsm.pLastTxMeInstance != nil {
1719 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1720 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1721 switch oFsm.pLastTxMeInstance.GetName() {
1722 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData":
1723 { // let the MultiEntity config proceed by stopping the wait function
1724 oFsm.mutexPLastTxMeInstance.RUnlock()
1725 oFsm.omciMIdsResponseReceived <- true
1726 return nil
1727 }
1728 default:
1729 {
1730 logger.Warnw(ctx, "Unsupported ME name received!",
1731 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1732 }
mpagenko01e726e2020-10-23 09:45:29 +00001733 }
1734 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001735 } else {
1736 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001737 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001738 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00001739 return nil
1740}
1741
dbainbri4d3a0dc2020-12-02 00:33:42 +00001742func (oFsm *UniVlanConfigFsm) performConfigEvtocdEntries(ctx context.Context, aFlowEntryNo uint8) error {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001743 if aFlowEntryNo == 0 {
1744 // EthType set only at first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00001745 // EVTOCD ME is expected to exist at this point already from MIB-Download (with AssociationType/Pointer)
1746 // we need to extend the configuration by EthType definition and, to be sure, downstream 'inverse' mode
dbainbri4d3a0dc2020-12-02 00:33:42 +00001747 logger.Debugw(ctx, "UniVlanConfigFsm Tx Create::EVTOCD", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00001748 "EntitytId": strconv.FormatInt(int64(oFsm.evtocdID), 16),
1749 "i/oEthType": strconv.FormatInt(int64(cDefaultTpid), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001750 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001751 associationType := 2 // default to uniPPTP
1752 if oFsm.pOnuUniPort.portType == uniVEIP {
1753 associationType = 10
1754 }
1755 // Create the EVTOCD ME
mpagenkodff5dda2020-08-28 11:52:01 +00001756 meParams := me.ParamData{
1757 EntityID: oFsm.evtocdID,
1758 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001759 "AssociationType": uint8(associationType),
1760 "AssociatedMePointer": oFsm.pOnuUniPort.entityID,
mpagenkodff5dda2020-08-28 11:52:01 +00001761 },
1762 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001763 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001764 meInstance, err := oFsm.pOmciCC.sendCreateEvtocdVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout,
1765 true, oFsm.pAdaptFsm.commChan, meParams)
1766 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001767 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001768 logger.Errorw(ctx, "CreateEvtocdVar create failed, aborting UniVlanConfigFsm!",
1769 log.Fields{"device-id": oFsm.deviceID})
1770 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1771 return fmt.Errorf("evtocd instance create failed %s, error %s", oFsm.deviceID, err)
1772 }
mpagenkodff5dda2020-08-28 11:52:01 +00001773 //accept also nil as (error) return value for writing to LastTx
1774 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001775 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001776 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001777
1778 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001779 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001780 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001781 logger.Errorw(ctx, "Evtocd create failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001782 log.Fields{"device-id": oFsm.deviceID})
1783 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1784 return fmt.Errorf("evtocd create failed %s, error %s", oFsm.deviceID, err)
1785 }
1786
1787 // Set the EVTOCD ME default params
1788 meParams = me.ParamData{
1789 EntityID: oFsm.evtocdID,
1790 Attributes: me.AttributeValueMap{
1791 "InputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
1792 "OutputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
1793 "DownstreamMode": uint8(cDefaultDownstreamMode),
1794 },
1795 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001796 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001797 meInstance, err = oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
1798 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001799 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001800 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001801 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001802 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
1803 log.Fields{"device-id": oFsm.deviceID})
1804 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1805 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
1806 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001807 //accept also nil as (error) return value for writing to LastTx
1808 // - this avoids misinterpretation of new received OMCI messages
1809 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001810 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001811
1812 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001813 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001814 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001815 logger.Errorw(ctx, "Evtocd set TPID failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001816 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301817 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001818 return fmt.Errorf("evtocd set TPID failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00001819 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001820 } //first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00001821
mpagenko551a4d42020-12-08 18:09:20 +00001822 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001823 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00001824 //transparent transmission required
mpagenko551a4d42020-12-08 18:09:20 +00001825 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001826 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged transparent rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001827 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001828 sliceEvtocdRule := make([]uint8, 16)
1829 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1830 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1831 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1832 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1833 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1834
1835 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1836 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
1837 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1838 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1839 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1840
1841 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1842 0<<cTreatTTROffset| // Do not pop any tags
1843 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1844 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1845 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1846
1847 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1848 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
1849 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1850 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
1851
1852 meParams := me.ParamData{
1853 EntityID: oFsm.evtocdID,
1854 Attributes: me.AttributeValueMap{
1855 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1856 },
1857 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001858 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001859 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
1860 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001861 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001862 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001863 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001864 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
1865 log.Fields{"device-id": oFsm.deviceID})
1866 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1867 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
1868 }
mpagenkodff5dda2020-08-28 11:52:01 +00001869 //accept also nil as (error) return value for writing to LastTx
1870 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001871 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001872 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001873
1874 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001875 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001876 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001877 logger.Errorw(ctx, "Evtocd set transparent singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001878 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301879 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001880 return fmt.Errorf("evtocd set transparent singletagged rule failed %s, error %s", oFsm.deviceID, err)
1881
mpagenkodff5dda2020-08-28 11:52:01 +00001882 }
1883 } else {
1884 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
1885 if oFsm.acceptIncrementalEvtoOption {
mpagenko9a304ea2020-12-16 15:54:01 +00001886 matchPcp := oFsm.actualUniVlanConfigRule.MatchPcp
1887 matchVid := oFsm.actualUniVlanConfigRule.MatchVid
1888 setPcp := oFsm.actualUniVlanConfigRule.SetPcp
1889 setVid := oFsm.actualUniVlanConfigRule.SetVid
mpagenkodff5dda2020-08-28 11:52:01 +00001890 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001891 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged translation rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001892 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001893 sliceEvtocdRule := make([]uint8, 16)
1894 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1895 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1896 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1897 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1898 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1899
1900 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00001901 oFsm.actualUniVlanConfigRule.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
1902 oFsm.actualUniVlanConfigRule.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
mpagenkodff5dda2020-08-28 11:52:01 +00001903 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1904 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1905
1906 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00001907 oFsm.actualUniVlanConfigRule.TagsToRemove<<cTreatTTROffset| // either 1 or 0
mpagenkodff5dda2020-08-28 11:52:01 +00001908 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1909 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1910 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1911
1912 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00001913 oFsm.actualUniVlanConfigRule.SetPcp<<cTreatPrioOffset| // as configured in flow
1914 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| //as configured in flow
mpagenkodff5dda2020-08-28 11:52:01 +00001915 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00001916 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001917
1918 meParams := me.ParamData{
1919 EntityID: oFsm.evtocdID,
1920 Attributes: me.AttributeValueMap{
1921 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1922 },
1923 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001924 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001925 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
1926 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001927 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001928 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001929 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001930 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
1931 log.Fields{"device-id": oFsm.deviceID})
1932 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1933 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
1934 }
mpagenkodff5dda2020-08-28 11:52:01 +00001935 //accept also nil as (error) return value for writing to LastTx
1936 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001937 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001938 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001939
1940 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001941 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001942 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001943 logger.Errorw(ctx, "Evtocd set singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001944 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301945 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001946 return fmt.Errorf("evtocd set singletagged translation rule failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00001947 }
1948 } else {
1949 //not transparent and not acceptIncrementalEvtoOption untagged/priotagged->singletagged
1950 { // just for local var's
1951 // this defines stacking scenario: untagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00001952 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD untagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001953 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001954 sliceEvtocdRule := make([]uint8, 16)
1955 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1956 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1957 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1958 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1959 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1960
1961 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1962 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
1963 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1964 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1965 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1966
1967 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1968 0<<cTreatTTROffset| // Do not pop any tags
1969 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1970 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1971 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1972
1973 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1974 0<<cTreatPrioOffset| // vlan prio set to 0
1975 // (as done in Py code, maybe better option would be setPcp here, which still could be 0?)
mpagenko9a304ea2020-12-16 15:54:01 +00001976 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| // Outer VID don't care
mpagenkodff5dda2020-08-28 11:52:01 +00001977 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
1978
mpagenko551a4d42020-12-08 18:09:20 +00001979 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001980 meParams := me.ParamData{
1981 EntityID: oFsm.evtocdID,
1982 Attributes: me.AttributeValueMap{
1983 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1984 },
1985 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001986 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001987 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
1988 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001989 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001990 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001991 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001992 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
1993 log.Fields{"device-id": oFsm.deviceID})
1994 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1995 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
1996 }
mpagenkodff5dda2020-08-28 11:52:01 +00001997 //accept also nil as (error) return value for writing to LastTx
1998 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001999 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002000 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002001
2002 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002003 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002004 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002005 logger.Errorw(ctx, "Evtocd set untagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002006 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302007 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002008 return fmt.Errorf("evtocd set untagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2009
mpagenkodff5dda2020-08-28 11:52:01 +00002010 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002011 } // just for local var's
mpagenkodff5dda2020-08-28 11:52:01 +00002012 { // just for local var's
2013 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002014 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD priotagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002015 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002016 sliceEvtocdRule := make([]uint8, 16)
2017 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2018 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2019 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2020 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2021 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2022
2023 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2024 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2025 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2026 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2027 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2028
2029 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2030 1<<cTreatTTROffset| // pop the prio-tag
2031 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2032 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2033 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2034
mpagenko551a4d42020-12-08 18:09:20 +00002035 oFsm.mutexFlowParams.RLock()
mpagenkodff5dda2020-08-28 11:52:01 +00002036 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2037 cCopyPrioFromInner<<cTreatPrioOffset| // vlan copy from PrioTag
2038 // (as done in Py code, maybe better option would be setPcp here, which still could be PrioCopy?)
mpagenko9a304ea2020-12-16 15:54:01 +00002039 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| // Outer VID as configured
mpagenkodff5dda2020-08-28 11:52:01 +00002040 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00002041 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002042
2043 meParams := me.ParamData{
2044 EntityID: oFsm.evtocdID,
2045 Attributes: me.AttributeValueMap{
2046 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2047 },
2048 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002049 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002050 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2051 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00002052 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002053 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002054 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002055 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2056 log.Fields{"device-id": oFsm.deviceID})
2057 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2058 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2059 }
mpagenkodff5dda2020-08-28 11:52:01 +00002060 //accept also nil as (error) return value for writing to LastTx
2061 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002062 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002063 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002064
2065 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002066 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002067 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002068 logger.Errorw(ctx, "Evtocd set priotagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002069 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302070 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002071 return fmt.Errorf("evtocd set priotagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2072
mpagenkodff5dda2020-08-28 11:52:01 +00002073 }
2074 } //just for local var's
2075 }
2076 }
2077
mpagenkofc4f56e2020-11-04 17:17:49 +00002078 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002079 logger.Debugw(ctx, "EVTOCD set loop finished", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002080 oFsm.configuredUniFlow++ // one (more) flow configured
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002081 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002082}
2083
dbainbri4d3a0dc2020-12-02 00:33:42 +00002084func (oFsm *UniVlanConfigFsm) removeEvtocdEntries(ctx context.Context, aRuleParams uniVlanRuleParams) {
mpagenko01e726e2020-10-23 09:45:29 +00002085 // configured Input/Output TPID is not modified again - no influence if no filter is applied
2086 if aRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
2087 //transparent transmission was set
2088 //perhaps the config is not needed for removal,
2089 // but the specific InnerTpid setting is removed in favor of the real default forwarding rule
dbainbri4d3a0dc2020-12-02 00:33:42 +00002090 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset to default single tagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002091 "device-id": oFsm.deviceID})
2092 sliceEvtocdRule := make([]uint8, 16)
2093 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2094 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2095 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2096 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2097 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2098
2099 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2100 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2101 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2102 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2103 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2104
2105 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2106 0<<cTreatTTROffset| // Do not pop any tags
2107 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2108 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2109 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2110
2111 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2112 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2113 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2114 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
2115
2116 meParams := me.ParamData{
2117 EntityID: oFsm.evtocdID,
2118 Attributes: me.AttributeValueMap{
2119 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2120 },
2121 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002122 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002123 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2124 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00002125 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002126 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002127 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002128 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2129 log.Fields{"device-id": oFsm.deviceID})
2130 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2131 return
2132 }
mpagenko01e726e2020-10-23 09:45:29 +00002133 //accept also nil as (error) return value for writing to LastTx
2134 // - this avoids misinterpretation of new received OMCI messages
2135 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002136 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002137
2138 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002139 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002140 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002141 logger.Errorw(ctx, "Evtocd reset singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002142 log.Fields{"device-id": oFsm.deviceID})
2143 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2144 return
2145 }
2146 } else {
2147 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
2148 if oFsm.acceptIncrementalEvtoOption {
2149 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002150 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear single tagged translation rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002151 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
2152 sliceEvtocdRule := make([]uint8, 16)
2153 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2154 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2155 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2156 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2157 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2158
2159 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2160 aRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2161 aRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2162 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2163 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2164
2165 // delete indication for the indicated Filter
2166 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2167 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2168
2169 meParams := me.ParamData{
2170 EntityID: oFsm.evtocdID,
2171 Attributes: me.AttributeValueMap{
2172 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2173 },
2174 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002175 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002176 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2177 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00002178 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002179 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002180 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002181 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2182 log.Fields{"device-id": oFsm.deviceID})
2183 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2184 return
2185 }
mpagenko01e726e2020-10-23 09:45:29 +00002186 //accept also nil as (error) return value for writing to LastTx
2187 // - this avoids misinterpretation of new received OMCI messages
2188 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002189 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002190
2191 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002192 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002193 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002194 logger.Errorw(ctx, "Evtocd clear singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002195 log.Fields{"device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
2196 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2197 return
2198 }
2199 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002200 // VOL-3685
2201 // NOTE: With ALPHA ONUs it was seen that just resetting a particular entry in the EVTOCD table
2202 // and re-configuring a new entry would not work. The old entry is removed and new entry is created
2203 // indeed, but the traffic landing upstream would carry old vlan sometimes.
2204 // This is only a WORKAROUND which basically deletes the entire EVTOCD ME and re-creates it again
2205 // later when the flow is being re-installed.
2206 // Of course this is applicable to case only where single service (or single tcont) is in use and
2207 // there is only one service vlan (oFsm.acceptIncrementalEvtoOption is false in this case).
2208 // Interstingly this problem has not been observed in multi-tcont (or multi-service) scenario (in
2209 // which case the oFsm.acceptIncrementalEvtoOption is set to true).
2210 if oFsm.configuredUniFlow == 0 && !oFsm.acceptIncrementalEvtoOption {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002211 logger.Debugw(ctx, "UniVlanConfigFsm Tx Remove::EVTOCD", log.Fields{"device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002212 // When there are no more EVTOCD vlan configurations on the ONU and acceptIncrementalEvtoOption
2213 // is not enabled, delete the EVTOCD ME.
mpagenko01e726e2020-10-23 09:45:29 +00002214 meParams := me.ParamData{
2215 EntityID: oFsm.evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002216 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002217 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002218 meInstance, err := oFsm.pOmciCC.sendDeleteEvtocd(log.WithSpanFromContext(context.TODO(), ctx),
2219 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00002220 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002221 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002222 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002223 logger.Errorw(ctx, "DeleteEvtocdVar delete failed, aborting UniVlanConfigFsm!",
2224 log.Fields{"device-id": oFsm.deviceID})
2225 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2226 return
2227 }
mpagenko01e726e2020-10-23 09:45:29 +00002228 //accept also nil as (error) return value for writing to LastTx
2229 // - this avoids misinterpretation of new received OMCI messages
2230 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002231 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002232
2233 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002234 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002235 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002236 logger.Errorw(ctx, "Evtocd delete rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002237 log.Fields{"device-id": oFsm.deviceID})
2238 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2239 return
2240 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002241 } else {
2242 // NOTE : We should ideally never ether this section when oFsm.acceptIncrementalEvtoOption is set to false
2243 // This is true for only ATT/DT workflow
dbainbri4d3a0dc2020-12-02 00:33:42 +00002244 logger.Debugw(ctx, "UniVlanConfigFsm: Remove EVTOCD set operation",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002245 log.Fields{"configured-flow": oFsm.configuredUniFlow, "incremental-evto": oFsm.acceptIncrementalEvtoOption})
2246 //not transparent and not acceptIncrementalEvtoOption: untagged/priotagged->singletagged
2247 { // just for local var's
2248 // this defines stacking scenario: untagged->singletagged
2249 //TODO!! in theory there could be different rules running in setting different PCP/VID'S
2250 // for untagged/priotagged, last rule wins (and remains the only one), maybe that should be
2251 // checked already at flow-add (and rejected) - to be observed if such is possible in Voltha
2252 // delete now assumes there is only one such rule!
dbainbri4d3a0dc2020-12-02 00:33:42 +00002253 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset untagged rule to default", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002254 "device-id": oFsm.deviceID})
2255 sliceEvtocdRule := make([]uint8, 16)
2256 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2257 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2258 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2259 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2260 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00002261
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002262 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2263 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2264 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2265 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2266 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00002267
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002268 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2269 0<<cTreatTTROffset| // Do not pop any tags
2270 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2271 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2272 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
mpagenko01e726e2020-10-23 09:45:29 +00002273
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002274 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2275 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2276 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2277 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
mpagenko01e726e2020-10-23 09:45:29 +00002278
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002279 meParams := me.ParamData{
2280 EntityID: oFsm.evtocdID,
2281 Attributes: me.AttributeValueMap{
2282 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2283 },
2284 }
ozgecanetsiab36ed572021-04-01 10:38:48 +03002285 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(context.TODO(),
2286 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002287 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002288 if err != nil {
2289 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2290 log.Fields{"device-id": oFsm.deviceID})
2291 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2292 return
2293 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002294 //accept also nil as (error) return value for writing to LastTx
2295 // - this avoids misinterpretation of new received OMCI messages
2296 oFsm.pLastTxMeInstance = meInstance
2297
2298 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002299 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002300 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002301 logger.Errorw(ctx, "Evtocd reset untagged rule to default failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002302 log.Fields{"device-id": oFsm.deviceID})
2303 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2304 return
2305 }
2306 } // just for local var's
2307 { // just for local var's
2308 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002309 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD delete priotagged rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002310 "device-id": oFsm.deviceID})
2311 sliceEvtocdRule := make([]uint8, 16)
2312 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2313 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2314 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2315 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2316 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2317
2318 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2319 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2320 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2321 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2322 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2323
2324 // delete indication for the indicated Filter
2325 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2326 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2327
2328 meParams := me.ParamData{
2329 EntityID: oFsm.evtocdID,
2330 Attributes: me.AttributeValueMap{
2331 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2332 },
2333 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002334 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002335 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2336 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002337 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002338 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002339 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002340 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2341 log.Fields{"device-id": oFsm.deviceID})
2342 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2343 return
2344 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002345 //accept also nil as (error) return value for writing to LastTx
2346 // - this avoids misinterpretation of new received OMCI messages
2347 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002348 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002349
2350 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002351 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002352 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002353 logger.Errorw(ctx, "Evtocd delete priotagged rule failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002354 log.Fields{"device-id": oFsm.deviceID})
2355 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2356 return
2357 }
mpagenko01e726e2020-10-23 09:45:29 +00002358 }
2359 } //just for local var's
2360 }
2361 }
2362
mpagenkofc4f56e2020-11-04 17:17:49 +00002363 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002364 logger.Debugw(ctx, "EVTOCD filter remove loop finished", log.Fields{"device-id": oFsm.deviceID})
Girish Gowdra26a40922021-01-29 17:14:34 -08002365 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRemFlowDone, aRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00002366}
2367
dbainbri4d3a0dc2020-12-02 00:33:42 +00002368func (oFsm *UniVlanConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00002369 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00002370 if oFsm.isCanceled {
2371 // FSM already canceled before entering wait
2372 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted (on enter)", log.Fields{"for device-id": oFsm.deviceID})
2373 oFsm.mutexIsAwaitingResponse.Unlock()
2374 return fmt.Errorf(cErrWaitAborted)
2375 }
mpagenko7d6bb022021-03-11 15:07:55 +00002376 oFsm.isAwaitingResponse = true
2377 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002378 select {
Himani Chawla26e555c2020-08-31 12:30:20 +05302379 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenkodff5dda2020-08-28 11:52:01 +00002380 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00002381 // logger.Infow(ctx,"LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00002382 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second): //AS FOR THE OTHER OMCI FSM's
dbainbri4d3a0dc2020-12-02 00:33:42 +00002383 logger.Warnw(ctx, "UniVlanConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002384 oFsm.mutexIsAwaitingResponse.Lock()
2385 oFsm.isAwaitingResponse = false
2386 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002387 return fmt.Errorf("uniVlanConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002388 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05302389 if success {
mpagenkocf48e452021-04-23 09:23:00 +00002390 logger.Debugw(ctx, "UniVlanConfigFsm multi entity response received", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002391 oFsm.mutexIsAwaitingResponse.Lock()
2392 oFsm.isAwaitingResponse = false
2393 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002394 return nil
2395 }
mpagenko7d6bb022021-03-11 15:07:55 +00002396 // waiting was aborted (probably on external request)
mpagenkocf48e452021-04-23 09:23:00 +00002397 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002398 oFsm.mutexIsAwaitingResponse.Lock()
2399 oFsm.isAwaitingResponse = false
2400 oFsm.mutexIsAwaitingResponse.Unlock()
2401 return fmt.Errorf(cErrWaitAborted)
mpagenkodff5dda2020-08-28 11:52:01 +00002402 }
2403}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002404
mpagenko551a4d42020-12-08 18:09:20 +00002405func (oFsm *UniVlanConfigFsm) performSettingMulticastME(ctx context.Context, tpID uint8, multicastGemPortID uint16, vlanID uint32) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002406 logger.Debugw(ctx, "Setting Multicast MEs", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002407 "multicastGemPortID": multicastGemPortID, "vlanID": vlanID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002408 errCreateMOP := oFsm.performCreatingMulticastOperationProfile(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002409 if errCreateMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002410 logger.Errorw(ctx, "MulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002411 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002412 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002413 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMOP)
2414 }
2415
dbainbri4d3a0dc2020-12-02 00:33:42 +00002416 errSettingMOP := oFsm.performSettingMulticastOperationProfile(ctx, multicastGemPortID, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002417 if errSettingMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002418 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002419 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002420 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002421 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errSettingMOP)
2422 }
2423
dbainbri4d3a0dc2020-12-02 00:33:42 +00002424 errCreateMSCI := oFsm.performCreatingMulticastSubscriberConfigInfo(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002425 if errCreateMSCI != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002426 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002427 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002428 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002429 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMSCI)
2430 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002431 macBpCdEID, errMacBpCdEID := generateMcastANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo))
2432 if errMacBpCdEID != nil {
2433 logger.Errorw(ctx, "MulticastMacBridgePortConfigData entity id generation failed, aborting AniConfig FSM!",
2434 log.Fields{"device-id": oFsm.deviceID})
2435 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2436 return fmt.Errorf("generateMcastANISideMBPCDEID responseError %s, error %s", oFsm.deviceID, errMacBpCdEID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002437
Mahir Gunyel6781f962021-05-16 23:30:08 -07002438 }
2439 logger.Debugw(ctx, "UniVlanConfigFsm set macBpCdEID for mcast", log.Fields{
2440 "EntitytId": strconv.FormatInt(int64(macBpCdEID), 16), "macBpNo": oFsm.pOnuUniPort.macBpNo,
2441 "in state": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002442 meParams := me.ParamData{
Mahir Gunyel6781f962021-05-16 23:30:08 -07002443 EntityID: macBpCdEID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002444 Attributes: me.AttributeValueMap{
2445 "BridgeIdPointer": macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo),
2446 "PortNum": 0xf0, //fixed unique ANI side indication
2447 "TpType": 6, //MCGemIWTP
2448 "TpPointer": multicastGemPortID,
2449 },
2450 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002451 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002452 meInstance, err := oFsm.pOmciCC.sendCreateMBPConfigDataVar(context.TODO(),
2453 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true, oFsm.pAdaptFsm.commChan, meParams)
2454 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002455 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002456 logger.Errorw(ctx, "MBPConfigDataVar create failed, aborting AniConfig FSM!",
2457 log.Fields{"device-id": oFsm.deviceID})
2458 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2459 return fmt.Errorf("creatingMulticastSubscriberConfigInfo createError #{oFsm.deviceID}, error #{err}")
2460 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002461 //accept also nil as (error) return value for writing to LastTx
2462 // - this avoids misinterpretation of new received OMCI messages
2463 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002464 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002465 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002466 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002467 logger.Errorw(ctx, "CreateMBPConfigData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002468 log.Fields{"device-id": oFsm.deviceID, "MBPConfigDataID": macBridgeServiceProfileEID})
mpagenko9a304ea2020-12-16 15:54:01 +00002469 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002470 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, err)
2471 }
2472
2473 // ==> Start creating VTFD for mcast vlan
2474
2475 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
2476 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07002477 mcastVtfdID := macBpCdEID
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002478
dbainbri4d3a0dc2020-12-02 00:33:42 +00002479 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD for mcast", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002480 "EntitytId": strconv.FormatInt(int64(mcastVtfdID), 16), "mcastVlanID": vlanID,
2481 "in state": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
2482 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
2483
2484 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
2485 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
2486 // new vlan associated with a different TP.
2487 vtfdFilterList[0] = uint16(vlanID)
2488
2489 meParams = me.ParamData{
2490 EntityID: mcastVtfdID,
2491 Attributes: me.AttributeValueMap{
2492 "VlanFilterList": vtfdFilterList,
2493 "ForwardOperation": uint8(0x10), //VID investigation
2494 "NumberOfEntries": oFsm.numVlanFilterEntries,
2495 },
2496 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002497 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002498 meInstance, err = oFsm.pOmciCC.sendCreateVtfdVar(context.TODO(),
2499 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true, oFsm.pAdaptFsm.commChan, meParams)
2500 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002501 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002502 logger.Errorw(ctx, "CreateVtfdVar create failed, aborting UniVlanConfigFsm!",
2503 log.Fields{"device-id": oFsm.deviceID})
2504 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2505 return fmt.Errorf("createMcastVlanFilterData creationError %s, error %s", oFsm.deviceID, err)
2506 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002507 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002508 oFsm.mutexPLastTxMeInstance.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002509 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002510 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002511 logger.Errorw(ctx, "CreateMcastVlanFilterData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002512 log.Fields{"device-id": oFsm.deviceID, "mcastVtfdID": mcastVtfdID})
mpagenko9a304ea2020-12-16 15:54:01 +00002513 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002514 return fmt.Errorf("createMcastVlanFilterData responseError %s, error %s", oFsm.deviceID, err)
2515 }
2516
2517 return nil
2518}
2519
dbainbri4d3a0dc2020-12-02 00:33:42 +00002520func (oFsm *UniVlanConfigFsm) performCreatingMulticastSubscriberConfigInfo(ctx context.Context) error {
Mahir Gunyel6781f962021-05-16 23:30:08 -07002521 instID, err := generateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002522 if err != nil {
Mahir Gunyel6781f962021-05-16 23:30:08 -07002523 logger.Errorw(ctx, "error generrating me instance id",
2524 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002525 return err
2526 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002527 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastSubscriberConfigInfo",
2528 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002529 meParams := me.ParamData{
2530 EntityID: instID,
2531 Attributes: me.AttributeValueMap{
2532 "MeType": 0,
2533 //Direct reference to the Operation profile
2534 //TODO ANI side used on UNI side, not the clearest option.
ozgecanetsia5c88b762021-03-23 10:27:15 +03002535 "MulticastOperationsProfilePointer": instID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002536 },
2537 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002538 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002539 meInstance, err := oFsm.pOmciCC.sendCreateMulticastSubConfigInfoVar(context.TODO(),
2540 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002541 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002542 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002543 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002544 logger.Errorw(ctx, "CreateMulticastSubConfigInfoVar create failed, aborting UniVlanConfigFSM!",
2545 log.Fields{"device-id": oFsm.deviceID})
2546 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2547 return fmt.Errorf("creatingMulticastSubscriberConfigInfo interface creationError %s, error %s",
2548 oFsm.deviceID, err)
2549 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002550 //accept also nil as (error) return value for writing to LastTx
2551 // - this avoids misinterpretation of new received OMCI messages
2552 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002553 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002554 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002555 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002556 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002557 logger.Errorw(ctx, "CreateMulticastSubConfigInfo create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002558 log.Fields{"device-id": oFsm.deviceID, "MulticastSubConfigInfo": instID})
2559 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s", oFsm.deviceID)
2560 }
2561 return nil
2562}
2563
dbainbri4d3a0dc2020-12-02 00:33:42 +00002564func (oFsm *UniVlanConfigFsm) performCreatingMulticastOperationProfile(ctx context.Context) error {
ozgecanetsia5c88b762021-03-23 10:27:15 +03002565 instID, err := oFsm.pDeviceHandler.getUniPortMEEntityID(oFsm.pOnuUniPort.portNo)
2566 if err != nil {
2567 logger.Errorw(ctx, "error fetching uni port me instance",
2568 log.Fields{"device-id": oFsm.deviceID, "portNo": oFsm.pOnuUniPort.portNo})
2569 return err
2570 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002571 instID += macBridgePortAniBaseEID
2572 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastOperationProfile",
2573 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002574 meParams := me.ParamData{
2575 EntityID: instID,
2576 Attributes: me.AttributeValueMap{
2577 "IgmpVersion": 2,
2578 "IgmpFunction": 0,
2579 //0 means false
2580 "ImmediateLeave": 0,
2581 "Robustness": 2,
2582 "QuerierIp": 0,
2583 "QueryInterval": 125,
2584 "QuerierMaxResponseTime": 100,
2585 "LastMemberResponseTime": 10,
2586 //0 means false
2587 "UnauthorizedJoinBehaviour": 0,
2588 },
2589 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002590 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002591 meInstance, err := oFsm.pOmciCC.sendCreateMulticastOperationProfileVar(context.TODO(),
2592 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002593 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002594 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002595 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002596 logger.Errorw(ctx, "CreateMulticastOperationProfileVar create failed, aborting UniVlanConfigFsm!",
2597 log.Fields{"device-id": oFsm.deviceID})
2598 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2599 return fmt.Errorf("createMulticastOperationProfileVar responseError %s, error %s", oFsm.deviceID, err)
2600 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002601 //accept also nil as (error) return value for writing to LastTx
2602 // - this avoids misinterpretation of new received OMCI messages
2603 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002604 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002605 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03002606 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002607 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002608 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002609 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03002610 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002611 }
2612 return nil
2613}
2614
dbainbri4d3a0dc2020-12-02 00:33:42 +00002615func (oFsm *UniVlanConfigFsm) performSettingMulticastOperationProfile(ctx context.Context, multicastGemPortID uint16, vlanID uint32) error {
ozgecanetsia5c88b762021-03-23 10:27:15 +03002616 instID, err := oFsm.pDeviceHandler.getUniPortMEEntityID(oFsm.pOnuUniPort.portNo)
2617 if err != nil {
2618 logger.Errorw(ctx, "error fetching uni port me instance",
2619 log.Fields{"device-id": oFsm.deviceID, "portNo": oFsm.pOnuUniPort.portNo})
2620 return err
2621 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002622 instID += macBridgePortAniBaseEID
2623 logger.Debugw(ctx, "UniVlanConfigFsm set MulticastOperationProfile",
2624 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002625 //TODO check that this is correct
2626 // Table control
2627 //setCtrl = 1
2628 //rowPartId = 0
2629 //test = 0
2630 //rowKey = 0
2631 tableCtrlStr := "0100000000000000"
2632 tableCtrl := AsByteSlice(tableCtrlStr)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002633 dynamicAccessCL := make([]uint8, 24)
2634 copy(dynamicAccessCL, tableCtrl)
2635 //Multicast GemPortId
2636 binary.BigEndian.PutUint16(dynamicAccessCL[2:], multicastGemPortID)
2637 // python version waits for installation of flows, see line 723 onward of
2638 // brcm_openomci_onu_handler.py
2639 binary.BigEndian.PutUint16(dynamicAccessCL[4:], uint16(vlanID))
2640 //Source IP all to 0
2641 binary.BigEndian.PutUint32(dynamicAccessCL[6:], IPToInt32(net.IPv4(0, 0, 0, 0)))
2642 //TODO start and end are hardcoded, get from TP
2643 // Destination IP address start of range
2644 binary.BigEndian.PutUint32(dynamicAccessCL[10:], IPToInt32(net.IPv4(225, 0, 0, 0)))
2645 // Destination IP address end of range
2646 binary.BigEndian.PutUint32(dynamicAccessCL[14:], IPToInt32(net.IPv4(239, 255, 255, 255)))
2647 //imputed group bandwidth
2648 binary.BigEndian.PutUint16(dynamicAccessCL[18:], 0)
2649
2650 meParams := me.ParamData{
2651 EntityID: instID,
2652 Attributes: me.AttributeValueMap{
2653 "DynamicAccessControlListTable": dynamicAccessCL,
2654 },
2655 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002656 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002657 meInstance, err := oFsm.pOmciCC.sendSetMulticastOperationProfileVar(context.TODO(),
2658 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002659 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002660 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002661 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002662 logger.Errorw(ctx, "SetMulticastOperationProfileVar set failed, aborting UniVlanConfigFsm!",
2663 log.Fields{"device-id": oFsm.deviceID})
2664 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2665 return fmt.Errorf("setMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
2666 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002667 //accept also nil as (error) return value for writing to LastTx
2668 // - this avoids misinterpretation of new received OMCI messages
2669 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002670 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002671 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03002672 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002673 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002674 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002675 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03002676 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002677 }
2678 return nil
2679}
Girish Gowdra26a40922021-01-29 17:14:34 -08002680
2681// IsFlowRemovePending returns true if there are pending flows to remove, else false.
mpagenkobb47bc22021-04-20 13:29:09 +00002682func (oFsm *UniVlanConfigFsm) IsFlowRemovePending(aFlowDeleteChannel chan<- bool) bool {
2683 oFsm.mutexFlowParams.Lock()
2684 defer oFsm.mutexFlowParams.Unlock()
2685 if len(oFsm.uniRemoveFlowsSlice) > 0 {
2686 //flow removal is still ongoing/pending
2687 oFsm.signalOnFlowDelete = true
2688 oFsm.flowDeleteChannel = aFlowDeleteChannel
2689 return true
2690 }
2691 return false
Girish Gowdra26a40922021-01-29 17:14:34 -08002692}