blob: 028245dd6bee6377401cd15cc2ce0d9737e463a7 [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
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200182 // Used to indicate if the FSM is for a reconciling flow and if it's the last flow to be reconciled
183 // thus notification needs to be sent on chan.
184 lastFlowToReconcile bool
mpagenkodff5dda2020-08-28 11:52:01 +0000185}
186
mpagenko01e726e2020-10-23 09:45:29 +0000187//NewUniVlanConfigFsm is the 'constructor' for the state machine to config the PON ANI ports
188// of ONU UNI ports via OMCI
dbainbri4d3a0dc2020-12-02 00:33:42 +0000189func NewUniVlanConfigFsm(ctx context.Context, apDeviceHandler *deviceHandler, apDevOmciCC *omciCC, apUniPort *onuUniPort,
mpagenko551a4d42020-12-08 18:09:20 +0000190 apUniTechProf *onuUniTechProf, apOnuDB *onuDeviceDB, aTechProfileID uint8,
mpagenko01e726e2020-10-23 09:45:29 +0000191 aRequestEvent OnuDeviceEvent, aName string, aCommChannel chan Message, aAcceptIncrementalEvto bool,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200192 aCookieSlice []uint64, aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, lastFlowToRec bool) *UniVlanConfigFsm {
mpagenkodff5dda2020-08-28 11:52:01 +0000193 instFsm := &UniVlanConfigFsm{
194 pDeviceHandler: apDeviceHandler,
mpagenko01e726e2020-10-23 09:45:29 +0000195 deviceID: apDeviceHandler.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +0000196 pOmciCC: apDevOmciCC,
197 pOnuUniPort: apUniPort,
198 pUniTechProf: apUniTechProf,
199 pOnuDB: apOnuDB,
mpagenkodff5dda2020-08-28 11:52:01 +0000200 requestEvent: aRequestEvent,
201 acceptIncrementalEvtoOption: aAcceptIncrementalEvto,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000202 numUniFlows: 0,
203 configuredUniFlow: 0,
mpagenko01e726e2020-10-23 09:45:29 +0000204 numRemoveFlows: 0,
mpagenko2418ab02020-11-12 12:58:06 +0000205 clearPersistency: true,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200206 lastFlowToReconcile: lastFlowToRec,
mpagenkodff5dda2020-08-28 11:52:01 +0000207 }
208
mpagenko01e726e2020-10-23 09:45:29 +0000209 instFsm.pAdaptFsm = NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
mpagenkodff5dda2020-08-28 11:52:01 +0000210 if instFsm.pAdaptFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000211 logger.Errorw(ctx, "UniVlanConfigFsm's AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000212 "device-id": instFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000213 return nil
214 }
mpagenkodff5dda2020-08-28 11:52:01 +0000215 instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
216 vlanStDisabled,
217 fsm.Events{
218 {Name: vlanEvStart, Src: []string{vlanStDisabled}, Dst: vlanStStarting},
219 {Name: vlanEvWaitTechProf, Src: []string{vlanStStarting}, Dst: vlanStWaitingTechProf},
mpagenko535d6ef2021-02-26 13:15:34 +0000220 {Name: vlanEvCancelOutstandingConfig, Src: []string{vlanStWaitingTechProf}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000221 {Name: vlanEvContinueConfig, Src: []string{vlanStWaitingTechProf}, Dst: vlanStConfigVtfd},
222 {Name: vlanEvStartConfig, Src: []string{vlanStStarting}, Dst: vlanStConfigVtfd},
223 {Name: vlanEvRxConfigVtfd, Src: []string{vlanStConfigVtfd}, Dst: vlanStConfigEvtocd},
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000224 {Name: vlanEvRxConfigEvtocd, Src: []string{vlanStConfigEvtocd, vlanStConfigIncrFlow},
225 Dst: vlanStConfigDone},
mpagenko551a4d42020-12-08 18:09:20 +0000226 {Name: vlanEvRenew, Src: []string{vlanStConfigDone}, Dst: vlanStStarting},
227 {Name: vlanEvWaitTPIncr, Src: []string{vlanStConfigDone}, Dst: vlanStIncrFlowWaitTP},
228 {Name: vlanEvIncrFlowConfig, Src: []string{vlanStConfigDone, vlanStIncrFlowWaitTP},
229 Dst: vlanStConfigIncrFlow},
mpagenko01e726e2020-10-23 09:45:29 +0000230 {Name: vlanEvRemFlowConfig, Src: []string{vlanStConfigDone}, Dst: vlanStRemoveFlow},
231 {Name: vlanEvRemFlowDone, Src: []string{vlanStRemoveFlow}, Dst: vlanStCleanupDone},
232 {Name: vlanEvFlowDataRemoved, Src: []string{vlanStCleanupDone}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000233 /*
234 {Name: vlanEvTimeoutSimple, Src: []string{
235 vlanStCreatingDot1PMapper, vlanStCreatingMBPCD, vlanStSettingTconts, vlanStSettingDot1PMapper}, Dst: vlanStStarting},
236 {Name: vlanEvTimeoutMids, Src: []string{
237 vlanStCreatingGemNCTPs, vlanStCreatingGemIWs, vlanStSettingPQs}, Dst: vlanStStarting},
238 */
239 // exceptional treatment for all states except vlanStResetting
240 {Name: vlanEvReset, Src: []string{vlanStStarting, vlanStWaitingTechProf,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000241 vlanStConfigVtfd, vlanStConfigEvtocd, vlanStConfigDone, vlanStConfigIncrFlow,
mpagenko01e726e2020-10-23 09:45:29 +0000242 vlanStRemoveFlow, vlanStCleanupDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000243 Dst: vlanStResetting},
244 // the only way to get to resource-cleared disabled state again is via "resseting"
245 {Name: vlanEvRestart, Src: []string{vlanStResetting}, Dst: vlanStDisabled},
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000246 // transitions for reconcile handling according to VOL-3834
247 {Name: vlanEvSkipOmciConfig, Src: []string{vlanStStarting}, Dst: vlanStConfigDone},
248 {Name: vlanEvSkipOmciConfig, Src: []string{vlanStConfigDone}, Dst: vlanStConfigIncrFlow},
249 {Name: vlanEvSkipIncFlowConfig, Src: []string{vlanStConfigIncrFlow}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000250 },
mpagenkodff5dda2020-08-28 11:52:01 +0000251 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000252 "enter_state": func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(ctx, e) },
253 "enter_" + vlanStStarting: func(e *fsm.Event) { instFsm.enterConfigStarting(ctx, e) },
254 "enter_" + vlanStConfigVtfd: func(e *fsm.Event) { instFsm.enterConfigVtfd(ctx, e) },
255 "enter_" + vlanStConfigEvtocd: func(e *fsm.Event) { instFsm.enterConfigEvtocd(ctx, e) },
256 "enter_" + vlanStConfigDone: func(e *fsm.Event) { instFsm.enterVlanConfigDone(ctx, e) },
257 "enter_" + vlanStConfigIncrFlow: func(e *fsm.Event) { instFsm.enterConfigIncrFlow(ctx, e) },
258 "enter_" + vlanStRemoveFlow: func(e *fsm.Event) { instFsm.enterRemoveFlow(ctx, e) },
259 "enter_" + vlanStCleanupDone: func(e *fsm.Event) { instFsm.enterVlanCleanupDone(ctx, e) },
260 "enter_" + vlanStResetting: func(e *fsm.Event) { instFsm.enterResetting(ctx, e) },
261 "enter_" + vlanStDisabled: func(e *fsm.Event) { instFsm.enterDisabled(ctx, e) },
mpagenkodff5dda2020-08-28 11:52:01 +0000262 },
263 )
264 if instFsm.pAdaptFsm.pFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000265 logger.Errorw(ctx, "UniVlanConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000266 "device-id": instFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000267 return nil
268 }
269
dbainbri4d3a0dc2020-12-02 00:33:42 +0000270 _ = instFsm.initUniFlowParams(ctx, aTechProfileID, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000271
dbainbri4d3a0dc2020-12-02 00:33:42 +0000272 logger.Debugw(ctx, "UniVlanConfigFsm created", log.Fields{"device-id": instFsm.deviceID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000273 "accIncrEvto": instFsm.acceptIncrementalEvtoOption})
mpagenkodff5dda2020-08-28 11:52:01 +0000274 return instFsm
275}
276
mpagenko01e726e2020-10-23 09:45:29 +0000277//initUniFlowParams is a simplified form of SetUniFlowParams() used for first flow parameters configuration
mpagenko551a4d42020-12-08 18:09:20 +0000278func (oFsm *UniVlanConfigFsm) initUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +0000279 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) error {
280 loRuleParams := uniVlanRuleParams{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000281 TpID: aTpID,
282 MatchVid: uint32(aMatchVlan),
283 SetVid: uint32(aSetVlan),
284 SetPcp: uint32(aSetPcp),
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000285 }
286 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
mpagenko01e726e2020-10-23 09:45:29 +0000287 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
288 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000289
mpagenko01e726e2020-10-23 09:45:29 +0000290 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000291 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000292 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000293 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
294 } else {
295 if !oFsm.acceptIncrementalEvtoOption {
296 //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 +0000297 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000298 }
299 }
300
mpagenko01e726e2020-10-23 09:45:29 +0000301 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000302 // no prio/vid filtering requested
mpagenko01e726e2020-10-23 09:45:29 +0000303 loRuleParams.TagsToRemove = 0 //no tag pop action
304 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
305 if loRuleParams.SetPcp == cCopyPrioFromInner {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000306 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
307 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
308 // might collide with NoMatchVid/CopyPrio(/setVid) setting
309 // this was some precondition setting taken over from py adapter ..
mpagenko01e726e2020-10-23 09:45:29 +0000310 loRuleParams.SetPcp = 0
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000311 }
312 }
mpagenko01e726e2020-10-23 09:45:29 +0000313
314 loFlowParams := uniVlanFlowParams{VlanRuleParams: loRuleParams}
315 loFlowParams.CookieSlice = make([]uint64, 0)
316 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
317
318 //no mutex protection is required for initial access and adding the first flow is always possible
319 oFsm.uniVlanFlowParamsSlice = make([]uniVlanFlowParams, 0)
320 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000321 logger.Debugw(ctx, "first UniVlanConfigFsm flow added", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000322 "Cookies": oFsm.uniVlanFlowParamsSlice[0].CookieSlice,
323 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
324 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
325 "SetPcp": loRuleParams.SetPcp,
326 "device-id": oFsm.deviceID})
327 oFsm.numUniFlows = 1
328 oFsm.uniRemoveFlowsSlice = make([]uniRemoveVlanFlowParams, 0) //initially nothing to remove
329
330 //permanently store flow config for reconcile case
dbainbri4d3a0dc2020-12-02 00:33:42 +0000331 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
mpagenkof1fc3862021-02-16 10:09:52 +0000332 &oFsm.uniVlanFlowParamsSlice, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000333 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000334 return err
335 }
336
337 return nil
338}
339
mpagenko7d6bb022021-03-11 15:07:55 +0000340//CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
mpagenko73143992021-04-09 15:17:10 +0000341func (oFsm *UniVlanConfigFsm) CancelProcessing(ctx context.Context) {
mpagenko7d6bb022021-03-11 15:07:55 +0000342 //mutex protection is required for possible concurrent access to FSM members
mpagenkocf48e452021-04-23 09:23:00 +0000343 oFsm.mutexIsAwaitingResponse.Lock()
344 oFsm.isCanceled = true
mpagenko7d6bb022021-03-11 15:07:55 +0000345 if oFsm.isAwaitingResponse {
mpagenkocf48e452021-04-23 09:23:00 +0000346 //attention: for an unbuffered channel the sender is blocked until the value is received (processed)!
347 // accordingly the mutex must be released before sending to channel here (mutex acquired in receiver)
348 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000349 //use channel to indicate that the response waiting shall be aborted
350 oFsm.omciMIdsResponseReceived <- false
mpagenkocf48e452021-04-23 09:23:00 +0000351 } else {
352 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000353 }
mpagenkocf48e452021-04-23 09:23:00 +0000354
mpagenko7d6bb022021-03-11 15:07:55 +0000355 // in any case (even if it might be automatically requested by above cancellation of waiting) ensure resetting the FSM
356 pAdaptFsm := oFsm.pAdaptFsm
357 if pAdaptFsm != nil {
mpagenkobb47bc22021-04-20 13:29:09 +0000358 if fsmErr := pAdaptFsm.pFsm.Event(vlanEvReset); fsmErr != nil {
mpagenkocf48e452021-04-23 09:23:00 +0000359 logger.Errorw(ctx, "reset-event failed in UniVlanConfigFsm!",
mpagenkobb47bc22021-04-20 13:29:09 +0000360 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000361 }
mpagenko7d6bb022021-03-11 15:07:55 +0000362 }
363}
364
mpagenko551a4d42020-12-08 18:09:20 +0000365//GetWaitingTpID returns the TpId that the FSM might be waiting for continuation (0 if none)
366func (oFsm *UniVlanConfigFsm) GetWaitingTpID() uint8 {
367 //mutex protection is required for possible concurrent access to FSM members
368 oFsm.mutexFlowParams.RLock()
369 defer oFsm.mutexFlowParams.RUnlock()
370 return oFsm.TpIDWaitingFor
371}
372
mpagenko2418ab02020-11-12 12:58:06 +0000373//RequestClearPersistency sets the internal flag to not clear persistency data (false=NoClear)
374func (oFsm *UniVlanConfigFsm) RequestClearPersistency(aClear bool) {
375 //mutex protection is required for possible concurrent access to FSM members
mpagenko15ff4a52021-03-02 10:09:20 +0000376 oFsm.mutexFlowParams.Lock()
377 defer oFsm.mutexFlowParams.Unlock()
mpagenko2418ab02020-11-12 12:58:06 +0000378 oFsm.clearPersistency = aClear
379}
380
mpagenko01e726e2020-10-23 09:45:29 +0000381//SetUniFlowParams verifies on existence of flow parameters to be configured,
382// optionally udates the cookie list or appends a new flow if there is space
383// if possible the FSM is trigggerd to start with the processing
mpagenko551a4d42020-12-08 18:09:20 +0000384// ignore complexity by now
385// nolint: gocyclo
386func (oFsm *UniVlanConfigFsm) SetUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200387 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, lastFlowToReconcile bool) error {
mpagenko01e726e2020-10-23 09:45:29 +0000388 loRuleParams := uniVlanRuleParams{
389 TpID: aTpID,
390 MatchVid: uint32(aMatchVlan),
391 SetVid: uint32(aSetVlan),
392 SetPcp: uint32(aSetPcp),
393 }
394 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
395 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
396 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
397
398 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
399 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
400 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
401 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
402 } else {
403 if !oFsm.acceptIncrementalEvtoOption {
404 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
405 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
406 }
407 }
408
409 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
410 // no prio/vid filtering requested
411 loRuleParams.TagsToRemove = 0 //no tag pop action
412 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
413 if loRuleParams.SetPcp == cCopyPrioFromInner {
414 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
415 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
416 // might collide with NoMatchVid/CopyPrio(/setVid) setting
417 // this was some precondition setting taken over from py adapter ..
418 loRuleParams.SetPcp = 0
419 }
420 }
421
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000422 flowEntryMatch := false
mpagenko01e726e2020-10-23 09:45:29 +0000423 flowCookieModify := false
mpagenkof1fc3862021-02-16 10:09:52 +0000424 requestAppendRule := false
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200425 oFsm.lastFlowToReconcile = lastFlowToReconcile
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000426 //mutex protection is required for possible concurrent access to FSM members
427 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +0000428 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
429 //TODO: Verify if using e.g. hashes for the structures here for comparison may generate
430 // countable run time optimization (perhaps with including the hash in kvStore storage?)
431 if storedUniFlowParams.VlanRuleParams == loRuleParams {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000432 flowEntryMatch = true
dbainbri4d3a0dc2020-12-02 00:33:42 +0000433 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - rule already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000434 "device-id": oFsm.deviceID})
435 var cookieMatch bool
436 for _, newCookie := range aCookieSlice { // for all cookies available in the arguments
437 cookieMatch = false
438 for _, cookie := range storedUniFlowParams.CookieSlice {
439 if cookie == newCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000440 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - and cookie already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000441 "device-id": oFsm.deviceID, "cookie": cookie})
442 cookieMatch = true
443 break //found new cookie - no further search for this requested cookie
444 }
445 }
446 if !cookieMatch {
mpagenkof1fc3862021-02-16 10:09:52 +0000447 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
448 if delayedCookie != 0 {
449 //a delay for adding the cookie to this rule is requested
450 // take care of the mutex which is already locked here, need to unlock/lock accordingly to prevent deadlock in suspension
451 oFsm.mutexFlowParams.Unlock()
452 oFsm.suspendNewRule(ctx)
453 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
454 oFsm.mutexFlowParams.Lock()
455 } else {
456 logger.Debugw(ctx, "UniVlanConfigFsm flow setting -adding new cookie", log.Fields{
457 "device-id": oFsm.deviceID, "cookie": newCookie})
458 //as range works with copies of the slice we have to write to the original slice!!
459 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
460 newCookie)
461 flowCookieModify = true
462 }
mpagenko01e726e2020-10-23 09:45:29 +0000463 }
464 } //for all new cookies
465 break // found rule - no further rule search
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000466 }
467 }
mpagenkof1fc3862021-02-16 10:09:52 +0000468 oFsm.mutexFlowParams.Unlock()
469
470 if !flowEntryMatch { //it is (was) a new rule
471 delayedCookie := oFsm.suspendIfRequiredNewRule(ctx, aCookieSlice)
472 requestAppendRule = true //default assumption here is that rule is to be appended
473 flowCookieModify = true //and that the the flow data base is to be updated
474 if delayedCookie != 0 { //it was suspended
475 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
476 }
477 }
478 kvStoreWrite := false //default setting is to not write to kvStore immediately - will be done on FSM execution finally
479 if requestAppendRule {
480 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000481 if oFsm.numUniFlows < cMaxAllowedFlows {
mpagenko01e726e2020-10-23 09:45:29 +0000482 loFlowParams := uniVlanFlowParams{VlanRuleParams: loRuleParams}
483 loFlowParams.CookieSlice = make([]uint64, 0)
484 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
485 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000486 logger.Debugw(ctx, "UniVlanConfigFsm flow add", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000487 "Cookies": oFsm.uniVlanFlowParamsSlice[oFsm.numUniFlows].CookieSlice,
488 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
489 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
Girish Gowdra041dcb32020-11-16 16:54:30 -0800490 "SetPcp": loRuleParams.SetPcp, "numberofFlows": oFsm.numUniFlows + 1,
mpagenko01e726e2020-10-23 09:45:29 +0000491 "device-id": oFsm.deviceID})
492
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000493 oFsm.numUniFlows++
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000494 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
495
496 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
497 logger.Debugw(ctx, "reconciling - skip omci-config of additional vlan rule",
498 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
mpagenkobb47bc22021-04-20 13:29:09 +0000499 //attention: take care to release the mutexFlowParams when calling the FSM directly -
500 // synchronous FSM 'event/state' functions may rely on this mutex
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000501 oFsm.mutexFlowParams.Unlock()
502 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
mpagenkobb47bc22021-04-20 13:29:09 +0000503 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvSkipOmciConfig); fsmErr != nil {
504 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
505 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
506 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000507 }
508 return nil
509 }
mpagenko01e726e2020-10-23 09:45:29 +0000510 // note: theoretical it would be possible to clear the same rule from the remove slice
511 // (for entries that have not yet been started with removal)
512 // but that is getting quite complicated - maybe a future optimization in case it should prove reasonable
513 // 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 +0000514
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000515 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
516 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
mpagenko551a4d42020-12-08 18:09:20 +0000517 if oFsm.configuredUniFlow == 0 {
518 // this is a restart with a complete new flow, we can re-use the initial flow config control
519 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenkobb47bc22021-04-20 13:29:09 +0000520 //attention: take care to release the mutexFlowParams when calling the FSM directly -
521 // synchronous FSM 'event/state' functions may rely on this mutex
522 oFsm.mutexFlowParams.Unlock()
523 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvRenew); fsmErr != nil {
524 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
525 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
526 }
mpagenko551a4d42020-12-08 18:09:20 +0000527 } else {
528 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000529 //store the actual rule that shall be worked upon in the following transient states
530 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +0000531 //tpId of the next rule to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000532 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko551a4d42020-12-08 18:09:20 +0000533 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, tpID)
534 oFsm.TpIDWaitingFor = tpID
mpagenko9a304ea2020-12-16 15:54:01 +0000535 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request (on setConfig)", log.Fields{
536 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
537 "set-Vlan": oFsm.actualUniVlanConfigRule.SetVid, "tp-id": tpID, "ProfDone": loTechProfDone})
mpagenkobb47bc22021-04-20 13:29:09 +0000538
539 //attention: take care to release the mutexFlowParams when calling the FSM directly -
540 // synchronous FSM 'event/state' functions may rely on this mutex
541 oFsm.mutexFlowParams.Unlock()
542 var fsmErr error
543 if loTechProfDone {
544 // let the vlan processing continue with next rule
545 fsmErr = pConfigVlanStateBaseFsm.Event(vlanEvIncrFlowConfig)
546 } else {
547 // set to waiting for Techprofile
548 fsmErr = pConfigVlanStateBaseFsm.Event(vlanEvWaitTPIncr)
549 }
550 if fsmErr != nil {
551 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
552 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
553 }
mpagenko551a4d42020-12-08 18:09:20 +0000554 }
mpagenkobb47bc22021-04-20 13:29:09 +0000555 } else {
556 // if not in the appropriate state a new entry will be automatically considered later
557 // when the configDone state is reached
558 oFsm.mutexFlowParams.Unlock()
559 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000560 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000561 logger.Errorw(ctx, "UniVlanConfigFsm flow limit exceeded", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000562 "device-id": oFsm.deviceID, "flow-number": oFsm.numUniFlows})
mpagenko15ff4a52021-03-02 10:09:20 +0000563 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000564 return fmt.Errorf(" UniVlanConfigFsm flow limit exceeded %s", oFsm.deviceID)
565 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000566 } else {
567 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
mpagenkof1fc3862021-02-16 10:09:52 +0000568 kvStoreWrite = true // ensure actual data write to kvStore immediately (no FSM activity)
mpagenko15ff4a52021-03-02 10:09:20 +0000569 oFsm.mutexFlowParams.RLock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000570 if oFsm.numUniFlows == oFsm.configuredUniFlow {
571 //all requested rules really have been configured
572 // state transition notification is checked in deviceHandler
mpagenko15ff4a52021-03-02 10:09:20 +0000573 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000574 if oFsm.pDeviceHandler != nil {
575 //also the related TechProfile was already configured
dbainbri4d3a0dc2020-12-02 00:33:42 +0000576 logger.Debugw(ctx, "UniVlanConfigFsm rule already set - send immediate add-success event for reason update", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +0000577 "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +0000578 // success indication without the need to write to kvStore (done already below with updated data from storePersUniFlowConfig())
579 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetAddNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000580 }
581 } else {
582 // avoid device reason update as the rule config connected to this flow may still be in progress
583 // and the device reason should only be updated on success of rule config
dbainbri4d3a0dc2020-12-02 00:33:42 +0000584 logger.Debugw(ctx, "UniVlanConfigFsm rule already set but configuration ongoing, suppress early add-success event for reason update",
mpagenkofc4f56e2020-11-04 17:17:49 +0000585 log.Fields{"device-id": oFsm.deviceID,
586 "NumberofRules": oFsm.numUniFlows, "Configured rules": oFsm.configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +0000587 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000588 }
589 }
mpagenko01e726e2020-10-23 09:45:29 +0000590
mpagenkof1fc3862021-02-16 10:09:52 +0000591 if flowCookieModify { // some change was done to the flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000592 //permanently store flow config for reconcile case
mpagenko15ff4a52021-03-02 10:09:20 +0000593 oFsm.mutexFlowParams.RLock()
mpagenkof1fc3862021-02-16 10:09:52 +0000594 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
595 &oFsm.uniVlanFlowParamsSlice, kvStoreWrite); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +0000596 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000597 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000598 return err
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000599 }
mpagenko15ff4a52021-03-02 10:09:20 +0000600 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000601 }
602 return nil
603}
604
mpagenkof1fc3862021-02-16 10:09:52 +0000605// VOL-3828 flow config sequence workaround ########### start ##########
606func (oFsm *UniVlanConfigFsm) delayNewRuleForCookie(ctx context.Context, aCookieSlice []uint64) uint64 {
607 //assumes mutexFlowParams.Lock() protection from caller!
608 if oFsm.delayNewRuleCookie == 0 && len(aCookieSlice) == 1 {
609 // if not already waiting, limitation for this workaround is to just have one overlapping cookie/rule
610 // suspend check is done only of there is only one cookie in the request
611 // background: more elements only expected in reconcile use case, where no conflicting sequence is to be expected
612 newCookie := aCookieSlice[0]
613 for _, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
614 for _, cookie := range storedUniFlowParams.CookieSlice {
615 if cookie == newCookie {
616 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - new cookie still exists for some rule", log.Fields{
617 "device-id": oFsm.deviceID, "cookie": cookie, "exists with SetVlan": storedUniFlowParams.VlanRuleParams.SetVid})
618 oFsm.delayNewRuleCookie = newCookie
619 return newCookie //found new cookie in some existing rule
620 }
621 } // for all stored cookies of the actual inspected rule
622 } //for all rules
623 }
624 return 0 //no delay requested
625}
626func (oFsm *UniVlanConfigFsm) suspendNewRule(ctx context.Context) {
627 oFsm.mutexFlowParams.RLock()
628 logger.Infow(ctx, "Need to suspend adding this rule as long as the cookie is still connected to some other rule", log.Fields{
629 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
630 oFsm.mutexFlowParams.RUnlock()
631 select {
632 case <-oFsm.chCookieDeleted:
633 logger.Infow(ctx, "resume adding this rule after having deleted cookie in some other rule", log.Fields{
634 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000635 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
mpagenkof1fc3862021-02-16 10:09:52 +0000636 logger.Errorw(ctx, "timeout waiting for deletion of cookie in some other rule, just try to continue", log.Fields{
637 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
638 }
639 oFsm.mutexFlowParams.Lock()
640 oFsm.delayNewRuleCookie = 0
641 oFsm.mutexFlowParams.Unlock()
642}
643func (oFsm *UniVlanConfigFsm) suspendIfRequiredNewRule(ctx context.Context, aCookieSlice []uint64) uint64 {
644 oFsm.mutexFlowParams.Lock()
645 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
646 oFsm.mutexFlowParams.Unlock()
647
648 if delayedCookie != 0 {
649 oFsm.suspendNewRule(ctx)
650 }
651 return delayedCookie
652}
653
654//returns flowModified, RuleAppendRequest
655func (oFsm *UniVlanConfigFsm) reviseFlowConstellation(ctx context.Context, aCookie uint64, aUniVlanRuleParams uniVlanRuleParams) (bool, bool) {
656 flowEntryMatch := false
657 oFsm.mutexFlowParams.Lock()
658 defer oFsm.mutexFlowParams.Unlock()
659 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
660 if storedUniFlowParams.VlanRuleParams == aUniVlanRuleParams {
661 flowEntryMatch = true
662 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - rule already exists", log.Fields{
663 "device-id": oFsm.deviceID})
664 cookieMatch := false
665 for _, cookie := range storedUniFlowParams.CookieSlice {
666 if cookie == aCookie {
667 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - and cookie already exists", log.Fields{
668 "device-id": oFsm.deviceID, "cookie": cookie})
669 cookieMatch = true
670 break //found new cookie - no further search for this requested cookie
671 }
672 }
673 if !cookieMatch {
674 logger.Debugw(ctx, "UniVlanConfigFsm flow revise -adding new cookie", log.Fields{
675 "device-id": oFsm.deviceID, "cookie": aCookie})
676 //as range works with copies of the slice we have to write to the original slice!!
677 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
678 aCookie)
679 return true, false //flowModified, NoRuleAppend
680 }
681 break // found rule - no further rule search
682 }
683 }
684 if !flowEntryMatch { //it is a new rule
685 return true, true //flowModified, RuleAppend
686 }
687 return false, false //flowNotModified, NoRuleAppend
688}
689
690// VOL-3828 flow config sequence workaround ########### end ##########
691
mpagenko01e726e2020-10-23 09:45:29 +0000692//RemoveUniFlowParams verifies on existence of flow cookie,
693// if found removes cookie from flow cookie list and if this is empty
694// initiates removal of the flow related configuration from the ONU (via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000695func (oFsm *UniVlanConfigFsm) RemoveUniFlowParams(ctx context.Context, aCookie uint64) error {
mpagenkof1fc3862021-02-16 10:09:52 +0000696 var deletedCookie uint64
mpagenko01e726e2020-10-23 09:45:29 +0000697 flowCookieMatch := false
698 //mutex protection is required for possible concurrent access to FSM members
699 oFsm.mutexFlowParams.Lock()
700 defer oFsm.mutexFlowParams.Unlock()
mpagenkof1fc3862021-02-16 10:09:52 +0000701remove_loop:
mpagenko01e726e2020-10-23 09:45:29 +0000702 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
703 for i, cookie := range storedUniFlowParams.CookieSlice {
704 if cookie == aCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000705 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - cookie found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000706 "device-id": oFsm.deviceID, "cookie": cookie})
707 flowCookieMatch = true
mpagenkof1fc3862021-02-16 10:09:52 +0000708 deletedCookie = aCookie
709 kvStoreWrite := false //default setting is to not write to kvStore immediately - will be done on FSM execution finally
mpagenko01e726e2020-10-23 09:45:29 +0000710 //remove the cookie from the cookie slice and verify it is getting empty
711 if len(storedUniFlowParams.CookieSlice) == 1 {
mpagenko535d6ef2021-02-26 13:15:34 +0000712 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
713 var cancelPendingConfig bool = false
714 var loRemoveParams uniRemoveVlanFlowParams = uniRemoveVlanFlowParams{}
dbainbri4d3a0dc2020-12-02 00:33:42 +0000715 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - full flow removal", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000716 "device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +0000717 //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 +0000718 // as the one still waiting in the FSM as toAdd but waiting for TechProfileConfig
mpagenko15ff4a52021-03-02 10:09:20 +0000719 // 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 +0000720 // if the Fsm is in some other transient (config) state, we will reach the DelRequest later and correctly process it then
721 if pConfigVlanStateBaseFsm.Is(vlanStWaitingTechProf) {
722 logger.Debugw(ctx, "UniVlanConfigFsm was waiting for TechProf config with this rule, aborting the outstanding config",
723 log.Fields{"device-id": oFsm.deviceID})
724 cancelPendingConfig = true
725 } else {
726 //create a new element for the removeVlanFlow slice
727 loRemoveParams = uniRemoveVlanFlowParams{
728 vlanRuleParams: storedUniFlowParams.VlanRuleParams,
729 cookie: aCookie,
730 }
731 oFsm.uniRemoveFlowsSlice = append(oFsm.uniRemoveFlowsSlice, loRemoveParams)
mpagenko01e726e2020-10-23 09:45:29 +0000732 }
mpagenko01e726e2020-10-23 09:45:29 +0000733
734 //and remove the actual element from the addVlanFlow slice
735 // oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = nil //automatically done by garbage collector
736 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
737 oFsm.numUniFlows = 0 //no more flows
738 oFsm.configuredUniFlow = 0 //no more flows configured
739 oFsm.uniVlanFlowParamsSlice = nil //reset the slice
mpagenko2418ab02020-11-12 12:58:06 +0000740 //at this point it is evident that no flow anymore refers to a still possibly active Techprofile
mpagenko535d6ef2021-02-26 13:15:34 +0000741 //request that this profile gets deleted before a new flow add is allowed (except for some aborted add)
742 if !cancelPendingConfig {
743 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, loRemoveParams.vlanRuleParams.TpID, true)
744 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000745 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - no more flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000746 "device-id": oFsm.deviceID})
747 } else {
748 oFsm.numUniFlows--
749 if oFsm.configuredUniFlow > 0 {
750 oFsm.configuredUniFlow--
751 //TODO!! might be needed to consider still outstanding configure requests ..
752 // so a flow at removal might still not be configured !?!
753 }
mpagenko2418ab02020-11-12 12:58:06 +0000754 usedTpID := storedUniFlowParams.VlanRuleParams.TpID
mpagenko01e726e2020-10-23 09:45:29 +0000755 //cut off the requested flow by slicing out this element
756 oFsm.uniVlanFlowParamsSlice = append(
757 oFsm.uniVlanFlowParamsSlice[:flow], oFsm.uniVlanFlowParamsSlice[flow+1:]...)
mpagenko2418ab02020-11-12 12:58:06 +0000758 //here we have to check, if there are still other flows referencing to the actual ProfileId
759 // before we can request that this profile gets deleted before a new flow add is allowed
mpagenkof1fc3862021-02-16 10:09:52 +0000760 // (needed to extract to function due to lint complexity)
mpagenko535d6ef2021-02-26 13:15:34 +0000761 if !cancelPendingConfig {
762 oFsm.updateTechProfileToDelete(ctx, usedTpID)
763 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000764 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow removed from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000765 "device-id": oFsm.deviceID})
766 }
767 //trigger the FSM to remove the relevant rule
mpagenko535d6ef2021-02-26 13:15:34 +0000768 if cancelPendingConfig {
769 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
mpagenkobb47bc22021-04-20 13:29:09 +0000770 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
771 // synchronous FSM 'event/state' functions may rely on this mutex
772 oFsm.mutexFlowParams.Unlock()
773 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvCancelOutstandingConfig); fsmErr != nil {
774 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
775 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
776 }
777 oFsm.mutexFlowParams.Lock()
mpagenko535d6ef2021-02-26 13:15:34 +0000778 } else {
779 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
780 logger.Debugw(ctx, "UniVlanConfigFsm rule removal request", log.Fields{
781 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
782 "tp-id": loRemoveParams.vlanRuleParams.TpID,
783 "set-Vlan": loRemoveParams.vlanRuleParams.SetVid})
784 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
mpagenkobb47bc22021-04-20 13:29:09 +0000785 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
786 // synchronous FSM 'event/state' functions may rely on this mutex
787 oFsm.mutexFlowParams.Unlock()
788 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvRemFlowConfig); fsmErr != nil {
789 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
790 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
791 }
792 oFsm.mutexFlowParams.Lock()
mpagenko535d6ef2021-02-26 13:15:34 +0000793 } // if not in the appropriate state a new entry will be automatically considered later
794 // when the configDone state is reached
795 }
mpagenko01e726e2020-10-23 09:45:29 +0000796 } else {
mpagenko01e726e2020-10-23 09:45:29 +0000797 //cut off the requested cookie by slicing out this element
798 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(
799 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[:i],
800 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[i+1:]...)
mpagenkofc4f56e2020-11-04 17:17:49 +0000801 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
mpagenkof1fc3862021-02-16 10:09:52 +0000802 kvStoreWrite = true // ensure actual data write to kvStore immediately (no FSM activity)
mpagenkofc4f56e2020-11-04 17:17:49 +0000803 // state transition notification is checked in deviceHandler
804 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000805 // success indication without the need to write to kvStore (done already below with updated data from storePersUniFlowConfig())
806 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000807 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000808 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - rule persists with still valid cookies", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000809 "device-id": oFsm.deviceID, "cookies": oFsm.uniVlanFlowParamsSlice[flow].CookieSlice})
mpagenkof1fc3862021-02-16 10:09:52 +0000810 if deletedCookie == oFsm.delayNewRuleCookie {
811 //the delayedNewCookie is the one that is currently deleted, but the rule still exist with other cookies
812 //as long as there are further cookies for this rule indicate there is still some cookie to be deleted
813 //simply use the first one
814 oFsm.delayNewRuleCookie = oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[0]
815 logger.Debugw(ctx, "UniVlanConfigFsm remaining cookie awaited for deletion before new rule add", log.Fields{
816 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
817 }
mpagenko01e726e2020-10-23 09:45:29 +0000818 }
mpagenko01e726e2020-10-23 09:45:29 +0000819 //permanently store the modified flow config for reconcile case
mpagenkofc4f56e2020-11-04 17:17:49 +0000820 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000821 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
822 &oFsm.uniVlanFlowParamsSlice, kvStoreWrite); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000823 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +0000824 return err
825 }
mpagenko01e726e2020-10-23 09:45:29 +0000826 }
mpagenkof1fc3862021-02-16 10:09:52 +0000827 break remove_loop //found the cookie - no further search for this requested cookie
mpagenko01e726e2020-10-23 09:45:29 +0000828 }
829 }
mpagenko01e726e2020-10-23 09:45:29 +0000830 } //search all flows
831 if !flowCookieMatch { //some cookie remove-request for a cookie that does not exist in the FSM data
dbainbri4d3a0dc2020-12-02 00:33:42 +0000832 logger.Warnw(ctx, "UniVlanConfigFsm flow removal - remove-cookie not found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000833 "device-id": oFsm.deviceID, "remove-cookie": aCookie})
834 // but accept the request with success as no such cookie (flow) does exist
mpagenkofc4f56e2020-11-04 17:17:49 +0000835 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
836 // state transition notification is checked in deviceHandler
837 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000838 // success indication without the need to write to kvStore (no change)
839 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000840 }
mpagenko01e726e2020-10-23 09:45:29 +0000841 return nil
842 } //unknown cookie
843
844 return nil
845}
846
mpagenkof1fc3862021-02-16 10:09:52 +0000847func (oFsm *UniVlanConfigFsm) updateTechProfileToDelete(ctx context.Context, usedTpID uint8) {
848 //here we have to check, if there are still other flows referencing to the actual ProfileId
849 // before we can request that this profile gets deleted before a new flow add is allowed
850 tpIDInOtherFlows := false
851 for _, tpUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
852 if tpUniFlowParams.VlanRuleParams.TpID == usedTpID {
853 tpIDInOtherFlows = true
854 break // search loop can be left
855 }
856 }
857 if tpIDInOtherFlows {
858 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is still used in other flows", log.Fields{
859 "device-id": oFsm.deviceID, "tp-id": usedTpID})
860 } else {
861 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is not used anymore", log.Fields{
862 "device-id": oFsm.deviceID, "tp-id": usedTpID})
863 //request that this profile gets deleted before a new flow add is allowed
864 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, usedTpID, true)
865 }
866}
867
dbainbri4d3a0dc2020-12-02 00:33:42 +0000868func (oFsm *UniVlanConfigFsm) enterConfigStarting(ctx context.Context, e *fsm.Event) {
869 logger.Debugw(ctx, "UniVlanConfigFsm start", log.Fields{"in state": e.FSM.Current(),
mpagenko01e726e2020-10-23 09:45:29 +0000870 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000871
872 // this FSM is not intended for re-start, needs always new creation for a new run
mpagenko01e726e2020-10-23 09:45:29 +0000873 // (self-destroying - compare enterDisabled())
mpagenkodff5dda2020-08-28 11:52:01 +0000874 oFsm.omciMIdsResponseReceived = make(chan bool)
mpagenkof1fc3862021-02-16 10:09:52 +0000875 oFsm.chCookieDeleted = make(chan bool)
mpagenkodff5dda2020-08-28 11:52:01 +0000876 // start go routine for processing of LockState messages
dbainbri4d3a0dc2020-12-02 00:33:42 +0000877 go oFsm.processOmciVlanMessages(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +0000878 //let the state machine run forward from here directly
879 pConfigVlanStateAFsm := oFsm.pAdaptFsm
880 if pConfigVlanStateAFsm != nil {
mpagenko9a304ea2020-12-16 15:54:01 +0000881
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000882 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
883 logger.Debugw(ctx, "reconciling - skip omci-config of vlan rule",
884 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
885 go func(a_pAFsm *AdapterFsm) {
886 _ = a_pAFsm.pFsm.Event(vlanEvSkipOmciConfig)
887 }(pConfigVlanStateAFsm)
888 return
889 }
890 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +0000891 //possibly the entry is not valid anymore based on intermediate delete requests
892 //just a basic protection ...
893 if len(oFsm.uniVlanFlowParamsSlice) == 0 {
894 oFsm.mutexFlowParams.Unlock()
895 logger.Debugw(ctx, "UniVlanConfigFsm start: no rule entry anymore available", log.Fields{
896 "device-id": oFsm.deviceID})
897 // Can't call FSM Event directly, decoupling it
898 go func(a_pAFsm *AdapterFsm) {
899 _ = a_pAFsm.pFsm.Event(vlanEvReset)
900 }(pConfigVlanStateAFsm)
901 return
902 }
mpagenko9a304ea2020-12-16 15:54:01 +0000903 //access to uniVlanFlowParamsSlice is done on first element only here per definition
904 //store the actual rule that shall be worked upon in the following transient states
905 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[0].VlanRuleParams
mpagenko9a304ea2020-12-16 15:54:01 +0000906 tpID := oFsm.actualUniVlanConfigRule.TpID
907 oFsm.TpIDWaitingFor = tpID
mpagenko551a4d42020-12-08 18:09:20 +0000908 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID))
mpagenko9a304ea2020-12-16 15:54:01 +0000909 logger.Debugw(ctx, "UniVlanConfigFsm - start with first rule", log.Fields{
910 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
911 "set-Vlan": oFsm.actualUniVlanConfigRule.SetVid, "tp-id": tpID, "ProfDone": loTechProfDone})
mpagenko551a4d42020-12-08 18:09:20 +0000912 //cmp also usage in EVTOCDE create in omci_cc
913 oFsm.evtocdID = macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo)
mpagenko535d6ef2021-02-26 13:15:34 +0000914 oFsm.mutexFlowParams.Unlock()
mpagenko9a304ea2020-12-16 15:54:01 +0000915 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +0000916 go func(aPAFsm *AdapterFsm, aTechProfDone bool) {
917 if aPAFsm != nil && aPAFsm.pFsm != nil {
918 if aTechProfDone {
mpagenkodff5dda2020-08-28 11:52:01 +0000919 // let the vlan processing begin
mpagenko551a4d42020-12-08 18:09:20 +0000920 _ = aPAFsm.pFsm.Event(vlanEvStartConfig)
mpagenkodff5dda2020-08-28 11:52:01 +0000921 } else {
922 // set to waiting for Techprofile
mpagenko551a4d42020-12-08 18:09:20 +0000923 _ = aPAFsm.pFsm.Event(vlanEvWaitTechProf)
mpagenkodff5dda2020-08-28 11:52:01 +0000924 }
925 }
mpagenko551a4d42020-12-08 18:09:20 +0000926 }(pConfigVlanStateAFsm, loTechProfDone)
927 } else {
928 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
929 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
930 //should never happen, else: recovery would be needed from outside the FSM
931 return
mpagenkodff5dda2020-08-28 11:52:01 +0000932 }
933}
934
dbainbri4d3a0dc2020-12-02 00:33:42 +0000935func (oFsm *UniVlanConfigFsm) enterConfigVtfd(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000936 //mutex protection is required for possible concurrent access to FSM members
937 oFsm.mutexFlowParams.Lock()
mpagenko551a4d42020-12-08 18:09:20 +0000938 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
mpagenko9a304ea2020-12-16 15:54:01 +0000939 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +0000940 // meaning transparent setup - no specific VTFD setting required
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000941 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000942 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000943 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000944 // let the FSM proceed ... (from within this state all internal pointers may be expected to be correct)
mpagenkodff5dda2020-08-28 11:52:01 +0000945 pConfigVlanStateAFsm := oFsm.pAdaptFsm
mpagenko9a304ea2020-12-16 15:54:01 +0000946 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +0000947 go func(a_pAFsm *AdapterFsm) {
Himani Chawla4d908332020-08-31 12:30:20 +0530948 _ = a_pAFsm.pFsm.Event(vlanEvRxConfigVtfd)
mpagenkodff5dda2020-08-28 11:52:01 +0000949 }(pConfigVlanStateAFsm)
950 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300951 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
952 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -0700953 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(oFsm.actualUniVlanConfigRule.TpID))
dbainbri4d3a0dc2020-12-02 00:33:42 +0000954 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300955 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -0700956 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
957 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": oFsm.actualUniVlanConfigRule.TpID})
mpagenko01e726e2020-10-23 09:45:29 +0000958 // setVid is assumed to be masked already by the caller to 12 bit
mpagenko9a304ea2020-12-16 15:54:01 +0000959 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000960 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000961 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000962 vtfdFilterList[0] = oFsm.vlanFilterList[0]
963 oFsm.numVlanFilterEntries = 1
mpagenkodff5dda2020-08-28 11:52:01 +0000964 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300965 EntityID: vtfdID,
mpagenkodff5dda2020-08-28 11:52:01 +0000966 Attributes: me.AttributeValueMap{
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000967 "VlanFilterList": vtfdFilterList, //omci lib wants a slice for serialization
968 "ForwardOperation": uint8(0x10), //VID investigation
969 "NumberOfEntries": oFsm.numVlanFilterEntries,
mpagenkodff5dda2020-08-28 11:52:01 +0000970 },
971 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000972 logger.Debugw(ctx, "UniVlanConfigFsm sendcreate VTFD", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000973 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000974 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300975 meInstance, err := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +0000976 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300977 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000978 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +0300979 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
980 log.Fields{"device-id": oFsm.deviceID})
981 pConfigVlanStateAFsm := oFsm.pAdaptFsm
982 if pConfigVlanStateAFsm != nil {
983 go func(a_pAFsm *AdapterFsm) {
984 _ = a_pAFsm.pFsm.Event(vlanEvReset)
985 }(pConfigVlanStateAFsm)
986 }
987 return
988 }
mpagenkodff5dda2020-08-28 11:52:01 +0000989 //accept also nil as (error) return value for writing to LastTx
990 // - this avoids misinterpretation of new received OMCI messages
991 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
992 // send shall return (dual format) error code that can be used here for immediate error treatment
993 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +0000994 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000995 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +0000996 }
997}
998
dbainbri4d3a0dc2020-12-02 00:33:42 +0000999func (oFsm *UniVlanConfigFsm) enterConfigEvtocd(ctx context.Context, e *fsm.Event) {
1000 logger.Debugw(ctx, "UniVlanConfigFsm - start config EVTOCD loop", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001001 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +00001002 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001003 go func() {
mpagenko9a304ea2020-12-16 15:54:01 +00001004 //using the first element in the slice because it's the first flow per definition here
1005 errEvto := oFsm.performConfigEvtocdEntries(ctx, 0)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001006 //This is correct passing scenario
1007 if errEvto == nil {
mpagenko9a304ea2020-12-16 15:54:01 +00001008 tpID := oFsm.actualUniVlanConfigRule.TpID
1009 vlanID := oFsm.actualUniVlanConfigRule.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +00001010 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
1011 logger.Infow(ctx, "Setting multicast MEs, with first flow", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001012 "techProfile": tpID, "gemPort": gemPort, "vlanID": vlanID, "configuredUniFlow": oFsm.configuredUniFlow})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001013 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001014 vlanID)
1015 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001016 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001017 log.Fields{"device-id": oFsm.deviceID})
1018 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1019 }
1020 }
1021 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
1022 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
1023 }
1024 }()
mpagenkodff5dda2020-08-28 11:52:01 +00001025}
1026
dbainbri4d3a0dc2020-12-02 00:33:42 +00001027func (oFsm *UniVlanConfigFsm) enterVlanConfigDone(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001028
mpagenko9a304ea2020-12-16 15:54:01 +00001029 oFsm.mutexFlowParams.RLock()
1030 defer oFsm.mutexFlowParams.RUnlock()
1031
mpagenkof1fc3862021-02-16 10:09:52 +00001032 logger.Infow(ctx, "UniVlanConfigFsm config done - checking on more flows", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00001033 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1034 "overall-uni-rules": oFsm.numUniFlows, "configured-uni-rules": oFsm.configuredUniFlow})
1035 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1036 if pConfigVlanStateAFsm == nil {
mpagenko551a4d42020-12-08 18:09:20 +00001037 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1038 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1039 //should never happen, else: recovery would be needed from outside the FSM
1040 return
1041 }
1042 pConfigVlanStateBaseFsm := pConfigVlanStateAFsm.pFsm
mpagenko01e726e2020-10-23 09:45:29 +00001043 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1044 //some further flows are to be removed, removal always starts with the first element
mpagenko9a304ea2020-12-16 15:54:01 +00001045 logger.Debugw(ctx, "UniVlanConfigFsm rule removal from ConfigDone", log.Fields{
1046 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
1047 "tp-id": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.TpID,
1048 "set-Vlan": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.SetVid})
1049 // Can't call FSM Event directly, decoupling it
mpagenko01e726e2020-10-23 09:45:29 +00001050 go func(a_pBaseFsm *fsm.FSM) {
1051 _ = a_pBaseFsm.Event(vlanEvRemFlowConfig)
1052 }(pConfigVlanStateBaseFsm)
1053 return
1054 }
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001055 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
1056 oFsm.configuredUniFlow = oFsm.numUniFlows
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001057 if oFsm.lastFlowToReconcile {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001058 logger.Debugw(ctx, "reconciling - flow processing finished", log.Fields{"device-id": oFsm.deviceID})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001059 oFsm.pDeviceHandler.setReconcilingFlows(false)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001060 oFsm.pDeviceHandler.chReconcilingFlowsFinished <- true
1061 }
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001062 logger.Debugw(ctx, "reconciling - skip enterVlanConfigDone processing",
1063 log.Fields{"numUniFlows": oFsm.numUniFlows, "configuredUniFlow": oFsm.configuredUniFlow, "device-id": oFsm.deviceID})
1064 return
1065 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001066 if oFsm.numUniFlows > oFsm.configuredUniFlow {
mpagenko551a4d42020-12-08 18:09:20 +00001067 if oFsm.configuredUniFlow == 0 {
mpagenko551a4d42020-12-08 18:09:20 +00001068 // this is a restart with a complete new flow, we can re-use the initial flow config control
1069 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenko9a304ea2020-12-16 15:54:01 +00001070 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001071 go func(a_pBaseFsm *fsm.FSM) {
1072 _ = a_pBaseFsm.Event(vlanEvRenew)
1073 }(pConfigVlanStateBaseFsm)
1074 return
1075 }
1076
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001077 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001078 //store the actual rule that shall be worked upon in the following transient states
1079 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +00001080 //tpId of the next rule to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001081 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko551a4d42020-12-08 18:09:20 +00001082 oFsm.TpIDWaitingFor = tpID
mpagenko551a4d42020-12-08 18:09:20 +00001083 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, tpID)
mpagenko9a304ea2020-12-16 15:54:01 +00001084 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request", log.Fields{
1085 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
1086 "set-Vlan": oFsm.actualUniVlanConfigRule.SetVid, "tp-id": tpID, "ProfDone": loTechProfDone})
1087 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001088 go func(aPBaseFsm *fsm.FSM, aTechProfDone bool) {
1089 if aTechProfDone {
1090 // let the vlan processing continue with next rule
1091 _ = aPBaseFsm.Event(vlanEvIncrFlowConfig)
1092 } else {
1093 // set to waiting for Techprofile
1094 _ = aPBaseFsm.Event(vlanEvWaitTPIncr)
1095 }
1096 }(pConfigVlanStateBaseFsm, loTechProfDone)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001097 return
1098 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001099 logger.Debugw(ctx, "UniVlanConfigFsm - VLAN config done: send dh event notification", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001100 "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001101 // it might appear that some flows are requested also after 'flowPushed' event has been generated ...
1102 // state transition notification is checked in deviceHandler
mpagenko551a4d42020-12-08 18:09:20 +00001103 // note: 'flowPushed' event is only generated if all 'pending' rules are configured
mpagenkodff5dda2020-08-28 11:52:01 +00001104 if oFsm.pDeviceHandler != nil {
mpagenkofc4f56e2020-11-04 17:17:49 +00001105 //making use of the add->remove successor enum assumption/definition
dbainbri4d3a0dc2020-12-02 00:33:42 +00001106 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(uint8(oFsm.requestEvent)+oFsm.requestEventOffset))
mpagenkodff5dda2020-08-28 11:52:01 +00001107 }
1108}
1109
dbainbri4d3a0dc2020-12-02 00:33:42 +00001110func (oFsm *UniVlanConfigFsm) enterConfigIncrFlow(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001111
1112 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
1113 logger.Debugw(ctx, "reconciling - skip further processing for incremental flow",
1114 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
1115 go func(a_pBaseFsm *fsm.FSM) {
1116 _ = a_pBaseFsm.Event(vlanEvSkipIncFlowConfig)
1117 }(oFsm.pAdaptFsm.pFsm)
1118 return
1119 }
mpagenko15ff4a52021-03-02 10:09:20 +00001120 oFsm.mutexFlowParams.Lock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001121 logger.Debugw(ctx, "UniVlanConfigFsm - start config further incremental flow", log.Fields{
Girish Gowdra041dcb32020-11-16 16:54:30 -08001122 "in state": e.FSM.Current(), "recent flow-number": oFsm.configuredUniFlow,
mpagenko01e726e2020-10-23 09:45:29 +00001123 "device-id": oFsm.deviceID})
mpagenko551a4d42020-12-08 18:09:20 +00001124 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001125
mpagenko9a304ea2020-12-16 15:54:01 +00001126 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001127 // meaning transparent setup - no specific VTFD setting required
1128 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001129 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001130 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001131 } else {
mpagenkocf48e452021-04-23 09:23:00 +00001132 //TODO!!!: it was not really intended to keep this enter* FSM method waiting on OMCI response (preventing other state transitions)
1133 // so it would be conceptually better to wait for the response in background like for the other multi-entity processing
1134 // but as the OMCI sequence must be ensured, a separate new state would be required - perhaps later
1135 // 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 +00001136 if oFsm.numVlanFilterEntries == 0 {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001137 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1138 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07001139 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(oFsm.actualUniVlanConfigRule.TpID))
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001140 //no VTFD yet created
dbainbri4d3a0dc2020-12-02 00:33:42 +00001141 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001142 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001143 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1144 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": oFsm.actualUniVlanConfigRule.TpID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001145 // 'SetVid' below is assumed to be masked already by the caller to 12 bit
mpagenko9a304ea2020-12-16 15:54:01 +00001146 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001147
mpagenko01e726e2020-10-23 09:45:29 +00001148 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001149 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1150 oFsm.numVlanFilterEntries = 1
1151 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001152 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001153 Attributes: me.AttributeValueMap{
1154 "VlanFilterList": vtfdFilterList,
1155 "ForwardOperation": uint8(0x10), //VID investigation
1156 "NumberOfEntries": oFsm.numVlanFilterEntries,
1157 },
1158 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001159 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001160 meInstance, err := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001161 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001162 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001163 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001164 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1165 log.Fields{"device-id": oFsm.deviceID})
1166 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1167 if pConfigVlanStateAFsm != nil {
1168 go func(a_pAFsm *AdapterFsm) {
1169 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1170 }(pConfigVlanStateAFsm)
1171 }
1172 return
1173 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001174 //accept also nil as (error) return value for writing to LastTx
1175 // - this avoids misinterpretation of new received OMCI messages
1176 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1177 // send shall return (dual format) error code that can be used here for immediate error treatment
1178 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001179 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001180 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001181 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001182 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1183 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07001184 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(oFsm.actualUniVlanConfigRule.TpID))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001185
dbainbri4d3a0dc2020-12-02 00:33:42 +00001186 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001187 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001188 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1189 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": oFsm.actualUniVlanConfigRule.TpID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001190 // setVid is assumed to be masked already by the caller to 12 bit
1191 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] =
mpagenko9a304ea2020-12-16 15:54:01 +00001192 uint16(oFsm.actualUniVlanConfigRule.SetVid)
mpagenko01e726e2020-10-23 09:45:29 +00001193 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001194
1195 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
1196 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
1197 // new vlan associated with a different TP.
mpagenko9a304ea2020-12-16 15:54:01 +00001198 vtfdFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001199
1200 oFsm.numVlanFilterEntries++
1201 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001202 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001203 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001204 "VlanFilterList": vtfdFilterList,
1205 "ForwardOperation": uint8(0x10), //VID investigation
1206 "NumberOfEntries": oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001207 },
1208 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001209 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001210 meInstance, err := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001211 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001212 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001213 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001214 logger.Errorw(ctx, "UniVlanFsm create Vlan Tagging Filter ME result error",
1215 log.Fields{"device-id": oFsm.deviceID, "Error": err})
1216 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1217 return
1218 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001219 //accept also nil as (error) return value for writing to LastTx
1220 // - this avoids misinterpretation of new received OMCI messages
1221 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1222 // send shall return (dual format) error code that can be used here for immediate error treatment
1223 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001224 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001225 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001226 }
mpagenko15ff4a52021-03-02 10:09:20 +00001227 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001228 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001229 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001230 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001231 logger.Errorw(ctx, "VTFD create/set failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001232 log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001233 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001234 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001235 go func(a_pBaseFsm *fsm.FSM) {
1236 _ = a_pBaseFsm.Event(vlanEvReset)
1237 }(pConfigVlanStateBaseFsm)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001238 return
1239 }
1240 }
mpagenko15ff4a52021-03-02 10:09:20 +00001241 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001242 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
mpagenko15ff4a52021-03-02 10:09:20 +00001243 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001244 go func() {
mpagenko15ff4a52021-03-02 10:09:20 +00001245 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001246 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko15ff4a52021-03-02 10:09:20 +00001247 configuredUniFlow := oFsm.configuredUniFlow
1248 oFsm.mutexFlowParams.RUnlock()
1249 errEvto := oFsm.performConfigEvtocdEntries(ctx, configuredUniFlow)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001250 //This is correct passing scenario
1251 if errEvto == nil {
1252 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
dbainbri4d3a0dc2020-12-02 00:33:42 +00001253 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
mpagenko15ff4a52021-03-02 10:09:20 +00001254 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001255 vlanID := oFsm.actualUniVlanConfigRule.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +00001256 logger.Infow(ctx, "Setting multicast MEs for additional flows", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001257 "techProfile": tpID, "gemPort": gemPort,
1258 "vlanID": vlanID, "configuredUniFlow": oFsm.configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +00001259 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001260 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001261 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001262 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001263 log.Fields{"device-id": oFsm.deviceID})
1264 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1265 }
1266 }
1267 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
1268 }
1269 }()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001270}
1271
dbainbri4d3a0dc2020-12-02 00:33:42 +00001272func (oFsm *UniVlanConfigFsm) enterRemoveFlow(ctx context.Context, e *fsm.Event) {
mpagenko551a4d42020-12-08 18:09:20 +00001273 oFsm.mutexFlowParams.RLock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001274 logger.Debugw(ctx, "UniVlanConfigFsm - start removing the top remove-flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001275 "in state": e.FSM.Current(), "with last cookie": oFsm.uniRemoveFlowsSlice[0].cookie,
1276 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001277
mpagenkofc4f56e2020-11-04 17:17:49 +00001278 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001279 loAllowSpecificOmciConfig := oFsm.pDeviceHandler.isReadyForOmciConfig()
mpagenko01e726e2020-10-23 09:45:29 +00001280 loVlanEntryClear := uint8(0)
1281 loVlanEntryRmPos := uint8(0x80) //with indication 'invalid' in bit 7
1282 //shallow copy is sufficient as no reference variables are used within struct
1283 loRuleParams := oFsm.uniRemoveFlowsSlice[0].vlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +00001284 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001285 logger.Debugw(ctx, "UniVlanConfigFsm - remove-flow parameters are", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001286 "match vid": loRuleParams.MatchVid, "match Pcp": loRuleParams.MatchPcp,
1287 "set vid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
1288 "device-id": oFsm.deviceID})
1289
1290 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
1291 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001292 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD removal required for transparent flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001293 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1294 } else {
1295 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization and 're-copy'
1296 if oFsm.numVlanFilterEntries == 1 {
Mahir Gunyel6781f962021-05-16 23:30:08 -07001297 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001298 //only one active VLAN entry (hopefully the SetVID we want to remove - should be, but not verified ..)
1299 // so we can just delete the VTFD entry
dbainbri4d3a0dc2020-12-02 00:33:42 +00001300 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD delete (no more vlan filters)",
Mahir Gunyel6781f962021-05-16 23:30:08 -07001301 log.Fields{"current vlan list": oFsm.vlanFilterList, "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
1302 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1303 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": loRuleParams.TpID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001304 loVlanEntryClear = 1 //full VlanFilter clear request
1305 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001306 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001307 meInstance, err := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001308 oFsm.pAdaptFsm.commChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001309 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001310 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001311 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1312 log.Fields{"device-id": oFsm.deviceID, "Error": err})
1313 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1314 return
1315 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001316 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001317 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001318 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001319 logger.Debugw(ctx, "UniVlanConfigFsm delete VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001320 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.getDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +00001321 }
mpagenko01e726e2020-10-23 09:45:29 +00001322 } else {
1323 //many VTFD already should exists - find and remove the one concerned by the actual remove rule
1324 // by updating the VTFD per set command with new valid list
dbainbri4d3a0dc2020-12-02 00:33:42 +00001325 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD removal of requested VLAN from the list on OMCI",
mpagenko01e726e2020-10-23 09:45:29 +00001326 log.Fields{"current vlan list": oFsm.vlanFilterList,
1327 "set-vlan": loRuleParams.SetVid, "device-id": oFsm.deviceID})
1328 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1329 if loRuleParams.SetVid == uint32(oFsm.vlanFilterList[i]) {
1330 loVlanEntryRmPos = i
1331 break //abort search
1332 }
1333 }
1334 if loVlanEntryRmPos < cVtfdTableSize {
Mahir Gunyel6781f962021-05-16 23:30:08 -07001335 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001336 //valid entry was found - to be eclipsed
1337 loVlanEntryClear = 2 //VlanFilter remove request for a specific entry
1338 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1339 if i < loVlanEntryRmPos {
1340 vtfdFilterList[i] = oFsm.vlanFilterList[i] //copy original
1341 } else if i < (cVtfdTableSize - 1) {
1342 vtfdFilterList[i] = oFsm.vlanFilterList[i+1] //copy successor (including 0 elements)
1343 } else {
1344 vtfdFilterList[i] = 0 //set last byte if needed
1345 }
1346 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001347 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001348 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001349 "new vlan list": vtfdFilterList, "device-id": oFsm.deviceID,
1350 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": loRuleParams.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001351
mpagenkofc4f56e2020-11-04 17:17:49 +00001352 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001353 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001354 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001355 meInstance, err := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001356 oFsm.pAdaptFsm.commChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001357 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001358 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001359 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1360 log.Fields{"device-id": oFsm.deviceID, "Error": err})
1361 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1362 return
1363 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001364 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001365 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001366 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001367 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001368 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.getDeviceReasonString()})
mpagenko01e726e2020-10-23 09:45:29 +00001369 }
mpagenko01e726e2020-10-23 09:45:29 +00001370 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001371 logger.Warnw(ctx, "UniVlanConfigFsm: requested VLAN for removal not found in list - ignore and continue (no VTFD set)",
mpagenko01e726e2020-10-23 09:45:29 +00001372 log.Fields{"device-id": oFsm.deviceID})
1373 }
1374 }
1375 if loVlanEntryClear > 0 {
mpagenkofc4f56e2020-11-04 17:17:49 +00001376 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
1377 //waiting on response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001378 err := oFsm.waitforOmciResponse(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001379 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001380 logger.Errorw(ctx, "VTFD delete/reset failed, aborting VlanConfig FSM!",
mpagenkofc4f56e2020-11-04 17:17:49 +00001381 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001382 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001383 go func(a_pBaseFsm *fsm.FSM) {
1384 _ = a_pBaseFsm.Event(vlanEvReset)
1385 }(pConfigVlanStateBaseFsm)
1386 return
1387 }
mpagenko01e726e2020-10-23 09:45:29 +00001388 }
1389
mpagenko15ff4a52021-03-02 10:09:20 +00001390 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00001391 if loVlanEntryClear == 1 {
1392 oFsm.vlanFilterList[0] = 0 //first entry is the only that can contain the previous only-one element
1393 oFsm.numVlanFilterEntries = 0
1394 } else if loVlanEntryClear == 2 {
1395 // new VlanFilterList should be one entry smaller now - copy from last configured entry
1396 // this loop now includes the 0 element on previous last valid entry
1397 for i := uint8(0); i <= oFsm.numVlanFilterEntries; i++ {
1398 oFsm.vlanFilterList[i] = vtfdFilterList[i]
1399 }
1400 oFsm.numVlanFilterEntries--
1401 }
mpagenko15ff4a52021-03-02 10:09:20 +00001402 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001403 }
1404 }
1405
mpagenkofc4f56e2020-11-04 17:17:49 +00001406 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001407 go oFsm.removeEvtocdEntries(ctx, loRuleParams)
mpagenkofc4f56e2020-11-04 17:17:49 +00001408 } else {
1409 // OMCI processing is not done, expectation is to have the ONU in some basic config state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001410 logger.Debugw(ctx, "UniVlanConfigFsm remove EVTOCD OMCI handling skipped based on device state", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +00001411 "device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001412 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001413 go func(a_pBaseFsm *fsm.FSM) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001414 _ = a_pBaseFsm.Event(vlanEvRemFlowDone, loRuleParams.TpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001415 }(pConfigVlanStateBaseFsm)
1416 }
mpagenkodff5dda2020-08-28 11:52:01 +00001417}
1418
dbainbri4d3a0dc2020-12-02 00:33:42 +00001419func (oFsm *UniVlanConfigFsm) enterVlanCleanupDone(ctx context.Context, e *fsm.Event) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001420 var tpID uint8
1421 // Extract the tpID
1422 if len(e.Args) > 0 {
1423 tpID = e.Args[0].(uint8)
1424 logger.Debugw(ctx, "UniVlanConfigFsm - flow removed for tp id", log.Fields{"device-id": oFsm.deviceID, "tpID": e.Args[0].(uint8)})
1425 } else {
1426 logger.Warnw(ctx, "UniVlanConfigFsm - tp id not available", log.Fields{"device-id": oFsm.deviceID})
1427 }
mpagenko01e726e2020-10-23 09:45:29 +00001428 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001429 deletedCookie := oFsm.uniRemoveFlowsSlice[0].cookie
1430 logger.Debugw(ctx, "UniVlanConfigFsm - removing the removal data", log.Fields{
1431 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1432 "removed cookie": deletedCookie, "waitForDeleteCookie": oFsm.delayNewRuleCookie})
1433
mpagenko01e726e2020-10-23 09:45:29 +00001434 if len(oFsm.uniRemoveFlowsSlice) <= 1 {
1435 oFsm.uniRemoveFlowsSlice = nil //reset the slice
dbainbri4d3a0dc2020-12-02 00:33:42 +00001436 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - last remove-flow deleted", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001437 "device-id": oFsm.deviceID})
1438 } else {
1439 //cut off the actual flow by slicing out the first element
1440 oFsm.uniRemoveFlowsSlice = append(
1441 oFsm.uniRemoveFlowsSlice[:0],
1442 oFsm.uniRemoveFlowsSlice[1:]...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001443 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow deleted from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001444 "device-id": oFsm.deviceID})
1445 }
1446 oFsm.mutexFlowParams.Unlock()
1447
mpagenkof1fc3862021-02-16 10:09:52 +00001448 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
mpagenko01e726e2020-10-23 09:45:29 +00001449 //return to the basic config verification state
mpagenkodff5dda2020-08-28 11:52:01 +00001450 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1451 if pConfigVlanStateAFsm != nil {
mpagenko9a304ea2020-12-16 15:54:01 +00001452 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +00001453 go func(a_pAFsm *AdapterFsm) {
1454 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001455 _ = a_pAFsm.pFsm.Event(vlanEvFlowDataRemoved)
mpagenkodff5dda2020-08-28 11:52:01 +00001456 }
1457 }(pConfigVlanStateAFsm)
1458 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001459
mpagenkobb47bc22021-04-20 13:29:09 +00001460 oFsm.mutexFlowParams.Lock()
Girish Gowdra26a40922021-01-29 17:14:34 -08001461 noOfFlowRem := len(oFsm.uniRemoveFlowsSlice)
mpagenkof1fc3862021-02-16 10:09:52 +00001462 if deletedCookie == oFsm.delayNewRuleCookie {
1463 // flush the channel CookieDeleted to ensure it is not lingering from some previous (aborted) activity
1464 select {
1465 case <-oFsm.chCookieDeleted:
1466 logger.Debug(ctx, "flushed CookieDeleted")
1467 default:
1468 }
1469 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue
1470 }
mpagenkobb47bc22021-04-20 13:29:09 +00001471 // If all pending flow-removes are completed and TP ID is valid go on processing any pending TP delete
1472 if oFsm.signalOnFlowDelete && noOfFlowRem == 0 && tpID > 0 {
1473 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 -08001474 // If we are here then all flows are removed.
mpagenkobb47bc22021-04-20 13:29:09 +00001475 if len(oFsm.flowDeleteChannel) == 0 { //channel not yet in use
1476 oFsm.flowDeleteChannel <- true
1477 oFsm.signalOnFlowDelete = false
1478 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001479 }
mpagenkobb47bc22021-04-20 13:29:09 +00001480 oFsm.mutexFlowParams.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001481}
1482
dbainbri4d3a0dc2020-12-02 00:33:42 +00001483func (oFsm *UniVlanConfigFsm) enterResetting(ctx context.Context, e *fsm.Event) {
1484 logger.Debugw(ctx, "UniVlanConfigFsm resetting", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001485
1486 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1487 if pConfigVlanStateAFsm != nil {
1488 // abort running message processing
1489 fsmAbortMsg := Message{
1490 Type: TestMsg,
1491 Data: TestMessage{
1492 TestMessageVal: AbortMessageProcessing,
1493 },
1494 }
1495 pConfigVlanStateAFsm.commChan <- fsmAbortMsg
1496
mpagenko9a304ea2020-12-16 15:54:01 +00001497 //try to restart the FSM to 'disabled'
1498 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +00001499 go func(a_pAFsm *AdapterFsm) {
1500 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301501 _ = a_pAFsm.pFsm.Event(vlanEvRestart)
mpagenkodff5dda2020-08-28 11:52:01 +00001502 }
1503 }(pConfigVlanStateAFsm)
1504 }
1505}
1506
dbainbri4d3a0dc2020-12-02 00:33:42 +00001507func (oFsm *UniVlanConfigFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
1508 logger.Debugw(ctx, "UniVlanConfigFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001509 oFsm.mutexPLastTxMeInstance.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00001510 oFsm.pLastTxMeInstance = nil
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001511 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001512 if oFsm.pDeviceHandler != nil {
mpagenko2418ab02020-11-12 12:58:06 +00001513 //TODO: to clarify with improved error treatment for VlanConfigFsm (timeout,reception) errors
1514 // current code removes the complete FSM including all flow/rule configuration done so far
1515 // this might be a bit to much, it would require fully new flow config from rwCore (at least on OnuDown/up)
1516 // maybe a more sophisticated approach is possible without clearing the data
mpagenko9a304ea2020-12-16 15:54:01 +00001517 oFsm.mutexFlowParams.RLock()
mpagenko2418ab02020-11-12 12:58:06 +00001518 if oFsm.clearPersistency {
1519 //permanently remove possibly stored persistent data
1520 if len(oFsm.uniVlanFlowParamsSlice) > 0 {
1521 var emptySlice = make([]uniVlanFlowParams, 0)
mpagenkof1fc3862021-02-16 10:09:52 +00001522 _ = oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID, &emptySlice, true) //ignore errors
mpagenko2418ab02020-11-12 12:58:06 +00001523 }
1524 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001525 logger.Debugw(ctx, "UniVlanConfigFsm persistency data not cleared", log.Fields{"device-id": oFsm.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001526 }
mpagenkof1fc3862021-02-16 10:09:52 +00001527 if oFsm.delayNewRuleCookie != 0 {
1528 // looks like the waiting AddFlow is stuck
1529 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue/treminate
1530 }
mpagenko9a304ea2020-12-16 15:54:01 +00001531 oFsm.mutexFlowParams.RUnlock()
mpagenko2418ab02020-11-12 12:58:06 +00001532 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001533 go oFsm.pDeviceHandler.RemoveVlanFilterFsm(ctx, oFsm.pOnuUniPort)
mpagenkodff5dda2020-08-28 11:52:01 +00001534 }
1535}
1536
dbainbri4d3a0dc2020-12-02 00:33:42 +00001537func (oFsm *UniVlanConfigFsm) processOmciVlanMessages(ctx context.Context) { //ctx context.Context?
1538 logger.Debugw(ctx, "Start UniVlanConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001539loop:
1540 for {
mpagenkodff5dda2020-08-28 11:52:01 +00001541 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00001542 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001543 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +05301544 message, ok := <-oFsm.pAdaptFsm.commChan
1545 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001546 logger.Info(ctx, "UniVlanConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301547 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
1548 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1549 break loop
1550 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001551 logger.Debugw(ctx, "UniVlanConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301552
1553 switch message.Type {
1554 case TestMsg:
1555 msg, _ := message.Data.(TestMessage)
1556 if msg.TestMessageVal == AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001557 logger.Infow(ctx, "UniVlanConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001558 break loop
1559 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001560 logger.Warnw(ctx, "UniVlanConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Himani Chawla4d908332020-08-31 12:30:20 +05301561 case OMCI:
1562 msg, _ := message.Data.(OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001563 oFsm.handleOmciVlanConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301564 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001565 logger.Warn(ctx, "UniVlanConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301566 "message.Type": message.Type})
mpagenkodff5dda2020-08-28 11:52:01 +00001567 }
1568 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001569 logger.Infow(ctx, "End UniVlanConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001570}
1571
dbainbri4d3a0dc2020-12-02 00:33:42 +00001572func (oFsm *UniVlanConfigFsm) handleOmciVlanConfigMessage(ctx context.Context, msg OmciMessage) {
1573 logger.Debugw(ctx, "Rx OMCI UniVlanConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001574 "msgType": msg.OmciMsg.MessageType})
1575
1576 switch msg.OmciMsg.MessageType {
1577 case omci.CreateResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001578 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001579 if err := oFsm.handleOmciCreateResponseMessage(ctx, msg.OmciPacket); err != nil {
1580 logger.Warnw(ctx, "CreateResponse handling aborted", log.Fields{"err": err})
mpagenkodff5dda2020-08-28 11:52:01 +00001581 return
1582 }
mpagenkodff5dda2020-08-28 11:52:01 +00001583 } //CreateResponseType
1584 case omci.SetResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001585 { //leave that here as direct code as most often used
mpagenkodff5dda2020-08-28 11:52:01 +00001586 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1587 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001588 logger.Errorw(ctx, "Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001589 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001590 return
1591 }
1592 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1593 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001594 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001595 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001596 return
1597 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001598 logger.Debugw(ctx, "UniVlanConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkodff5dda2020-08-28 11:52:01 +00001599 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001600 logger.Errorw(ctx, "UniVlanConfigFsm Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001601 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
mpagenkodff5dda2020-08-28 11:52:01 +00001602 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1603 return
1604 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001605 oFsm.mutexPLastTxMeInstance.RLock()
1606 if oFsm.pLastTxMeInstance != nil {
1607 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1608 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1609 switch oFsm.pLastTxMeInstance.GetName() {
1610 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "MulticastOperationsProfile":
1611 { // let the MultiEntity config proceed by stopping the wait function
1612 oFsm.mutexPLastTxMeInstance.RUnlock()
1613 oFsm.omciMIdsResponseReceived <- true
1614 return
1615 }
1616 default:
1617 {
1618 logger.Warnw(ctx, "Unsupported ME name received!",
1619 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1620 }
mpagenkodff5dda2020-08-28 11:52:01 +00001621 }
1622 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001623 } else {
1624 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001625 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001626 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001627 } //SetResponseType
mpagenko01e726e2020-10-23 09:45:29 +00001628 case omci.DeleteResponseType:
1629 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001630 if err := oFsm.handleOmciDeleteResponseMessage(ctx, msg.OmciPacket); err != nil {
1631 logger.Warnw(ctx, "DeleteResponse handling aborted", log.Fields{"err": err})
mpagenko01e726e2020-10-23 09:45:29 +00001632 return
1633 }
1634 } //DeleteResponseType
mpagenkodff5dda2020-08-28 11:52:01 +00001635 default:
1636 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001637 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00001638 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001639 return
1640 }
1641 }
1642}
1643
dbainbri4d3a0dc2020-12-02 00:33:42 +00001644func (oFsm *UniVlanConfigFsm) handleOmciCreateResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00001645 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeCreateResponse)
1646 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001647 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001648 log.Fields{"device-id": oFsm.deviceID})
1649 return fmt.Errorf("omci msg layer could not be detected for CreateResponse for device-id %x",
1650 oFsm.deviceID)
1651 }
1652 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
1653 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001654 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001655 log.Fields{"device-id": oFsm.deviceID})
1656 return fmt.Errorf("omci msg layer could not be assigned for CreateResponse for device-id %x",
1657 oFsm.deviceID)
1658 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001659 logger.Debugw(ctx, "UniVlanConfigFsm CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001660 if msgObj.Result != me.Success && msgObj.Result != me.InstanceExists {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001661 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"device-id": oFsm.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00001662 "Error": msgObj.Result})
1663 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1664 return fmt.Errorf("omci CreateResponse Error for device-id %x",
1665 oFsm.deviceID)
1666 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001667 oFsm.mutexPLastTxMeInstance.RLock()
1668 if oFsm.pLastTxMeInstance != nil {
1669 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1670 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1671 // to satisfy StaticCodeAnalysis I had to move the small processing into a separate method :-(
1672 switch oFsm.pLastTxMeInstance.GetName() {
1673 case "VlanTaggingFilterData", "MulticastOperationsProfile",
1674 "MulticastSubscriberConfigInfo", "MacBridgePortConfigurationData",
1675 "ExtendedVlanTaggingOperationConfigurationData":
1676 {
1677 oFsm.mutexPLastTxMeInstance.RUnlock()
1678 if oFsm.pAdaptFsm.pFsm.Current() == vlanStConfigVtfd {
1679 // Only if CreateResponse is received from first flow entry - let the FSM proceed ...
1680 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigVtfd)
1681 } else { // let the MultiEntity config proceed by stopping the wait function
1682 oFsm.omciMIdsResponseReceived <- true
1683 }
1684 return nil
1685 }
1686 default:
1687 {
1688 logger.Warnw(ctx, "Unsupported ME name received!",
1689 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001690 }
1691 }
1692 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001693 } else {
1694 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001695 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001696 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00001697 return nil
1698}
1699
dbainbri4d3a0dc2020-12-02 00:33:42 +00001700func (oFsm *UniVlanConfigFsm) handleOmciDeleteResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00001701 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeDeleteResponse)
1702 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001703 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001704 log.Fields{"device-id": oFsm.deviceID})
1705 return fmt.Errorf("omci msg layer could not be detected for DeleteResponse for device-id %x",
1706 oFsm.deviceID)
1707 }
1708 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
1709 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001710 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001711 log.Fields{"device-id": oFsm.deviceID})
1712 return fmt.Errorf("omci msg layer could not be assigned for DeleteResponse for device-id %x",
1713 oFsm.deviceID)
1714 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001715 logger.Debugw(ctx, "UniVlanConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko01e726e2020-10-23 09:45:29 +00001716 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001717 logger.Errorw(ctx, "UniVlanConfigFsm - Omci DeleteResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001718 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1719 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1720 return fmt.Errorf("omci DeleteResponse Error for device-id %x",
1721 oFsm.deviceID)
1722 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001723 oFsm.mutexPLastTxMeInstance.RLock()
1724 if oFsm.pLastTxMeInstance != nil {
1725 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1726 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1727 switch oFsm.pLastTxMeInstance.GetName() {
1728 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData":
1729 { // let the MultiEntity config proceed by stopping the wait function
1730 oFsm.mutexPLastTxMeInstance.RUnlock()
1731 oFsm.omciMIdsResponseReceived <- true
1732 return nil
1733 }
1734 default:
1735 {
1736 logger.Warnw(ctx, "Unsupported ME name received!",
1737 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1738 }
mpagenko01e726e2020-10-23 09:45:29 +00001739 }
1740 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001741 } else {
1742 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001743 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001744 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00001745 return nil
1746}
1747
dbainbri4d3a0dc2020-12-02 00:33:42 +00001748func (oFsm *UniVlanConfigFsm) performConfigEvtocdEntries(ctx context.Context, aFlowEntryNo uint8) error {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001749 if aFlowEntryNo == 0 {
1750 // EthType set only at first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00001751 // EVTOCD ME is expected to exist at this point already from MIB-Download (with AssociationType/Pointer)
1752 // we need to extend the configuration by EthType definition and, to be sure, downstream 'inverse' mode
dbainbri4d3a0dc2020-12-02 00:33:42 +00001753 logger.Debugw(ctx, "UniVlanConfigFsm Tx Create::EVTOCD", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00001754 "EntitytId": strconv.FormatInt(int64(oFsm.evtocdID), 16),
1755 "i/oEthType": strconv.FormatInt(int64(cDefaultTpid), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001756 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001757 associationType := 2 // default to uniPPTP
1758 if oFsm.pOnuUniPort.portType == uniVEIP {
1759 associationType = 10
1760 }
1761 // Create the EVTOCD ME
mpagenkodff5dda2020-08-28 11:52:01 +00001762 meParams := me.ParamData{
1763 EntityID: oFsm.evtocdID,
1764 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001765 "AssociationType": uint8(associationType),
1766 "AssociatedMePointer": oFsm.pOnuUniPort.entityID,
mpagenkodff5dda2020-08-28 11:52:01 +00001767 },
1768 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001769 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001770 meInstance, err := oFsm.pOmciCC.sendCreateEvtocdVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout,
1771 true, oFsm.pAdaptFsm.commChan, meParams)
1772 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001773 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001774 logger.Errorw(ctx, "CreateEvtocdVar create failed, aborting UniVlanConfigFsm!",
1775 log.Fields{"device-id": oFsm.deviceID})
1776 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1777 return fmt.Errorf("evtocd instance create failed %s, error %s", oFsm.deviceID, err)
1778 }
mpagenkodff5dda2020-08-28 11:52:01 +00001779 //accept also nil as (error) return value for writing to LastTx
1780 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001781 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001782 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001783
1784 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001785 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001786 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001787 logger.Errorw(ctx, "Evtocd create failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001788 log.Fields{"device-id": oFsm.deviceID})
1789 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1790 return fmt.Errorf("evtocd create failed %s, error %s", oFsm.deviceID, err)
1791 }
1792
1793 // Set the EVTOCD ME default params
1794 meParams = me.ParamData{
1795 EntityID: oFsm.evtocdID,
1796 Attributes: me.AttributeValueMap{
1797 "InputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
1798 "OutputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
1799 "DownstreamMode": uint8(cDefaultDownstreamMode),
1800 },
1801 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001802 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001803 meInstance, err = oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
1804 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001805 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001806 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001807 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001808 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
1809 log.Fields{"device-id": oFsm.deviceID})
1810 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1811 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
1812 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001813 //accept also nil as (error) return value for writing to LastTx
1814 // - this avoids misinterpretation of new received OMCI messages
1815 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001816 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001817
1818 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001819 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001820 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001821 logger.Errorw(ctx, "Evtocd set TPID failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001822 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301823 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001824 return fmt.Errorf("evtocd set TPID failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00001825 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001826 } //first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00001827
mpagenko551a4d42020-12-08 18:09:20 +00001828 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001829 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00001830 //transparent transmission required
mpagenko551a4d42020-12-08 18:09:20 +00001831 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001832 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged transparent rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001833 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001834 sliceEvtocdRule := make([]uint8, 16)
1835 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1836 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1837 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1838 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1839 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1840
1841 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1842 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
1843 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1844 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1845 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1846
1847 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1848 0<<cTreatTTROffset| // Do not pop any tags
1849 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1850 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1851 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1852
1853 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1854 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
1855 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1856 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
1857
1858 meParams := me.ParamData{
1859 EntityID: oFsm.evtocdID,
1860 Attributes: me.AttributeValueMap{
1861 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1862 },
1863 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001864 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001865 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
1866 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001867 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001868 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001869 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001870 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
1871 log.Fields{"device-id": oFsm.deviceID})
1872 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1873 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
1874 }
mpagenkodff5dda2020-08-28 11:52:01 +00001875 //accept also nil as (error) return value for writing to LastTx
1876 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001877 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001878 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001879
1880 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001881 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001882 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001883 logger.Errorw(ctx, "Evtocd set transparent singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001884 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301885 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001886 return fmt.Errorf("evtocd set transparent singletagged rule failed %s, error %s", oFsm.deviceID, err)
1887
mpagenkodff5dda2020-08-28 11:52:01 +00001888 }
1889 } else {
1890 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
1891 if oFsm.acceptIncrementalEvtoOption {
mpagenko9a304ea2020-12-16 15:54:01 +00001892 matchPcp := oFsm.actualUniVlanConfigRule.MatchPcp
1893 matchVid := oFsm.actualUniVlanConfigRule.MatchVid
1894 setPcp := oFsm.actualUniVlanConfigRule.SetPcp
1895 setVid := oFsm.actualUniVlanConfigRule.SetVid
mpagenkodff5dda2020-08-28 11:52:01 +00001896 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001897 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged translation rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001898 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001899 sliceEvtocdRule := make([]uint8, 16)
1900 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1901 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1902 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1903 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1904 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1905
1906 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00001907 oFsm.actualUniVlanConfigRule.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
1908 oFsm.actualUniVlanConfigRule.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
mpagenkodff5dda2020-08-28 11:52:01 +00001909 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1910 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1911
1912 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00001913 oFsm.actualUniVlanConfigRule.TagsToRemove<<cTreatTTROffset| // either 1 or 0
mpagenkodff5dda2020-08-28 11:52:01 +00001914 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1915 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1916 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1917
1918 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00001919 oFsm.actualUniVlanConfigRule.SetPcp<<cTreatPrioOffset| // as configured in flow
1920 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| //as configured in flow
mpagenkodff5dda2020-08-28 11:52:01 +00001921 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00001922 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001923
1924 meParams := me.ParamData{
1925 EntityID: oFsm.evtocdID,
1926 Attributes: me.AttributeValueMap{
1927 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1928 },
1929 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001930 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001931 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
1932 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001933 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001934 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001935 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001936 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
1937 log.Fields{"device-id": oFsm.deviceID})
1938 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1939 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
1940 }
mpagenkodff5dda2020-08-28 11:52:01 +00001941 //accept also nil as (error) return value for writing to LastTx
1942 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001943 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001944 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001945
1946 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001947 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001948 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001949 logger.Errorw(ctx, "Evtocd set singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001950 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301951 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001952 return fmt.Errorf("evtocd set singletagged translation rule failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00001953 }
1954 } else {
1955 //not transparent and not acceptIncrementalEvtoOption untagged/priotagged->singletagged
1956 { // just for local var's
1957 // this defines stacking scenario: untagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00001958 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD untagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001959 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001960 sliceEvtocdRule := make([]uint8, 16)
1961 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1962 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1963 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1964 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1965 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1966
1967 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1968 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
1969 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1970 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1971 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1972
1973 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1974 0<<cTreatTTROffset| // Do not pop any tags
1975 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1976 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1977 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1978
1979 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1980 0<<cTreatPrioOffset| // vlan prio set to 0
1981 // (as done in Py code, maybe better option would be setPcp here, which still could be 0?)
mpagenko9a304ea2020-12-16 15:54:01 +00001982 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| // Outer VID don't care
mpagenkodff5dda2020-08-28 11:52:01 +00001983 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
1984
mpagenko551a4d42020-12-08 18:09:20 +00001985 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001986 meParams := me.ParamData{
1987 EntityID: oFsm.evtocdID,
1988 Attributes: me.AttributeValueMap{
1989 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1990 },
1991 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001992 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001993 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
1994 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001995 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001996 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001997 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001998 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
1999 log.Fields{"device-id": oFsm.deviceID})
2000 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2001 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2002 }
mpagenkodff5dda2020-08-28 11:52:01 +00002003 //accept also nil as (error) return value for writing to LastTx
2004 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002005 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002006 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002007
2008 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002009 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002010 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002011 logger.Errorw(ctx, "Evtocd set untagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002012 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302013 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002014 return fmt.Errorf("evtocd set untagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2015
mpagenkodff5dda2020-08-28 11:52:01 +00002016 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002017 } // just for local var's
mpagenkodff5dda2020-08-28 11:52:01 +00002018 { // just for local var's
2019 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002020 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD priotagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002021 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002022 sliceEvtocdRule := make([]uint8, 16)
2023 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2024 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2025 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2026 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2027 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2028
2029 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2030 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2031 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2032 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2033 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2034
2035 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2036 1<<cTreatTTROffset| // pop the prio-tag
2037 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2038 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2039 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2040
mpagenko551a4d42020-12-08 18:09:20 +00002041 oFsm.mutexFlowParams.RLock()
mpagenkodff5dda2020-08-28 11:52:01 +00002042 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2043 cCopyPrioFromInner<<cTreatPrioOffset| // vlan copy from PrioTag
2044 // (as done in Py code, maybe better option would be setPcp here, which still could be PrioCopy?)
mpagenko9a304ea2020-12-16 15:54:01 +00002045 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| // Outer VID as configured
mpagenkodff5dda2020-08-28 11:52:01 +00002046 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00002047 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002048
2049 meParams := me.ParamData{
2050 EntityID: oFsm.evtocdID,
2051 Attributes: me.AttributeValueMap{
2052 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2053 },
2054 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002055 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002056 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2057 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00002058 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002059 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002060 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002061 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2062 log.Fields{"device-id": oFsm.deviceID})
2063 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2064 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2065 }
mpagenkodff5dda2020-08-28 11:52:01 +00002066 //accept also nil as (error) return value for writing to LastTx
2067 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002068 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002069 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002070
2071 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002072 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002073 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002074 logger.Errorw(ctx, "Evtocd set priotagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002075 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302076 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002077 return fmt.Errorf("evtocd set priotagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2078
mpagenkodff5dda2020-08-28 11:52:01 +00002079 }
2080 } //just for local var's
2081 }
2082 }
2083
mpagenkofc4f56e2020-11-04 17:17:49 +00002084 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002085 logger.Debugw(ctx, "EVTOCD set loop finished", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002086 oFsm.configuredUniFlow++ // one (more) flow configured
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002087 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002088}
2089
dbainbri4d3a0dc2020-12-02 00:33:42 +00002090func (oFsm *UniVlanConfigFsm) removeEvtocdEntries(ctx context.Context, aRuleParams uniVlanRuleParams) {
mpagenko01e726e2020-10-23 09:45:29 +00002091 // configured Input/Output TPID is not modified again - no influence if no filter is applied
2092 if aRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
2093 //transparent transmission was set
2094 //perhaps the config is not needed for removal,
2095 // but the specific InnerTpid setting is removed in favor of the real default forwarding rule
dbainbri4d3a0dc2020-12-02 00:33:42 +00002096 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset to default single tagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002097 "device-id": oFsm.deviceID})
2098 sliceEvtocdRule := make([]uint8, 16)
2099 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2100 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2101 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2102 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2103 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2104
2105 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2106 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2107 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2108 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2109 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2110
2111 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2112 0<<cTreatTTROffset| // Do not pop any tags
2113 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2114 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2115 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2116
2117 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2118 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2119 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2120 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
2121
2122 meParams := me.ParamData{
2123 EntityID: oFsm.evtocdID,
2124 Attributes: me.AttributeValueMap{
2125 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2126 },
2127 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002128 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002129 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2130 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00002131 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002132 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002133 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002134 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2135 log.Fields{"device-id": oFsm.deviceID})
2136 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2137 return
2138 }
mpagenko01e726e2020-10-23 09:45:29 +00002139 //accept also nil as (error) return value for writing to LastTx
2140 // - this avoids misinterpretation of new received OMCI messages
2141 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002142 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002143
2144 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002145 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002146 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002147 logger.Errorw(ctx, "Evtocd reset singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002148 log.Fields{"device-id": oFsm.deviceID})
2149 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2150 return
2151 }
2152 } else {
2153 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
2154 if oFsm.acceptIncrementalEvtoOption {
2155 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002156 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear single tagged translation rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002157 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
2158 sliceEvtocdRule := make([]uint8, 16)
2159 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2160 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2161 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2162 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2163 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2164
2165 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2166 aRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2167 aRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2168 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2169 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2170
2171 // delete indication for the indicated Filter
2172 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2173 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2174
2175 meParams := me.ParamData{
2176 EntityID: oFsm.evtocdID,
2177 Attributes: me.AttributeValueMap{
2178 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2179 },
2180 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002181 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002182 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2183 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00002184 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002185 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002186 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002187 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2188 log.Fields{"device-id": oFsm.deviceID})
2189 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2190 return
2191 }
mpagenko01e726e2020-10-23 09:45:29 +00002192 //accept also nil as (error) return value for writing to LastTx
2193 // - this avoids misinterpretation of new received OMCI messages
2194 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002195 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002196
2197 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002198 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002199 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002200 logger.Errorw(ctx, "Evtocd clear singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002201 log.Fields{"device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
2202 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2203 return
2204 }
2205 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002206 // VOL-3685
2207 // NOTE: With ALPHA ONUs it was seen that just resetting a particular entry in the EVTOCD table
2208 // and re-configuring a new entry would not work. The old entry is removed and new entry is created
2209 // indeed, but the traffic landing upstream would carry old vlan sometimes.
2210 // This is only a WORKAROUND which basically deletes the entire EVTOCD ME and re-creates it again
2211 // later when the flow is being re-installed.
2212 // Of course this is applicable to case only where single service (or single tcont) is in use and
2213 // there is only one service vlan (oFsm.acceptIncrementalEvtoOption is false in this case).
2214 // Interstingly this problem has not been observed in multi-tcont (or multi-service) scenario (in
2215 // which case the oFsm.acceptIncrementalEvtoOption is set to true).
2216 if oFsm.configuredUniFlow == 0 && !oFsm.acceptIncrementalEvtoOption {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002217 logger.Debugw(ctx, "UniVlanConfigFsm Tx Remove::EVTOCD", log.Fields{"device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002218 // When there are no more EVTOCD vlan configurations on the ONU and acceptIncrementalEvtoOption
2219 // is not enabled, delete the EVTOCD ME.
mpagenko01e726e2020-10-23 09:45:29 +00002220 meParams := me.ParamData{
2221 EntityID: oFsm.evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002222 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002223 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002224 meInstance, err := oFsm.pOmciCC.sendDeleteEvtocd(log.WithSpanFromContext(context.TODO(), ctx),
2225 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00002226 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002227 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002228 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002229 logger.Errorw(ctx, "DeleteEvtocdVar delete failed, aborting UniVlanConfigFsm!",
2230 log.Fields{"device-id": oFsm.deviceID})
2231 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2232 return
2233 }
mpagenko01e726e2020-10-23 09:45:29 +00002234 //accept also nil as (error) return value for writing to LastTx
2235 // - this avoids misinterpretation of new received OMCI messages
2236 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002237 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002238
2239 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002240 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002241 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002242 logger.Errorw(ctx, "Evtocd delete rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002243 log.Fields{"device-id": oFsm.deviceID})
2244 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2245 return
2246 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002247 } else {
2248 // NOTE : We should ideally never ether this section when oFsm.acceptIncrementalEvtoOption is set to false
2249 // This is true for only ATT/DT workflow
dbainbri4d3a0dc2020-12-02 00:33:42 +00002250 logger.Debugw(ctx, "UniVlanConfigFsm: Remove EVTOCD set operation",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002251 log.Fields{"configured-flow": oFsm.configuredUniFlow, "incremental-evto": oFsm.acceptIncrementalEvtoOption})
2252 //not transparent and not acceptIncrementalEvtoOption: untagged/priotagged->singletagged
2253 { // just for local var's
2254 // this defines stacking scenario: untagged->singletagged
2255 //TODO!! in theory there could be different rules running in setting different PCP/VID'S
2256 // for untagged/priotagged, last rule wins (and remains the only one), maybe that should be
2257 // checked already at flow-add (and rejected) - to be observed if such is possible in Voltha
2258 // delete now assumes there is only one such rule!
dbainbri4d3a0dc2020-12-02 00:33:42 +00002259 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset untagged rule to default", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002260 "device-id": oFsm.deviceID})
2261 sliceEvtocdRule := make([]uint8, 16)
2262 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2263 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2264 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2265 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2266 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00002267
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002268 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2269 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2270 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2271 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2272 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00002273
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002274 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2275 0<<cTreatTTROffset| // Do not pop any tags
2276 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2277 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2278 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
mpagenko01e726e2020-10-23 09:45:29 +00002279
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002280 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2281 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2282 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2283 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
mpagenko01e726e2020-10-23 09:45:29 +00002284
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002285 meParams := me.ParamData{
2286 EntityID: oFsm.evtocdID,
2287 Attributes: me.AttributeValueMap{
2288 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2289 },
2290 }
ozgecanetsiab36ed572021-04-01 10:38:48 +03002291 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(context.TODO(),
2292 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002293 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002294 if err != nil {
2295 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2296 log.Fields{"device-id": oFsm.deviceID})
2297 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2298 return
2299 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002300 //accept also nil as (error) return value for writing to LastTx
2301 // - this avoids misinterpretation of new received OMCI messages
2302 oFsm.pLastTxMeInstance = meInstance
2303
2304 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002305 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002306 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002307 logger.Errorw(ctx, "Evtocd reset untagged rule to default failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002308 log.Fields{"device-id": oFsm.deviceID})
2309 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2310 return
2311 }
2312 } // just for local var's
2313 { // just for local var's
2314 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002315 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD delete priotagged rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002316 "device-id": oFsm.deviceID})
2317 sliceEvtocdRule := make([]uint8, 16)
2318 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2319 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2320 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2321 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2322 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2323
2324 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2325 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2326 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2327 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2328 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2329
2330 // delete indication for the indicated Filter
2331 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2332 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2333
2334 meParams := me.ParamData{
2335 EntityID: oFsm.evtocdID,
2336 Attributes: me.AttributeValueMap{
2337 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2338 },
2339 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002340 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002341 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2342 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002343 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002344 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002345 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002346 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2347 log.Fields{"device-id": oFsm.deviceID})
2348 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2349 return
2350 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002351 //accept also nil as (error) return value for writing to LastTx
2352 // - this avoids misinterpretation of new received OMCI messages
2353 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002354 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002355
2356 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002357 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002358 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002359 logger.Errorw(ctx, "Evtocd delete priotagged rule failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002360 log.Fields{"device-id": oFsm.deviceID})
2361 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2362 return
2363 }
mpagenko01e726e2020-10-23 09:45:29 +00002364 }
2365 } //just for local var's
2366 }
2367 }
2368
mpagenkofc4f56e2020-11-04 17:17:49 +00002369 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002370 logger.Debugw(ctx, "EVTOCD filter remove loop finished", log.Fields{"device-id": oFsm.deviceID})
Girish Gowdra26a40922021-01-29 17:14:34 -08002371 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRemFlowDone, aRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00002372}
2373
dbainbri4d3a0dc2020-12-02 00:33:42 +00002374func (oFsm *UniVlanConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00002375 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00002376 if oFsm.isCanceled {
2377 // FSM already canceled before entering wait
2378 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted (on enter)", log.Fields{"for device-id": oFsm.deviceID})
2379 oFsm.mutexIsAwaitingResponse.Unlock()
2380 return fmt.Errorf(cErrWaitAborted)
2381 }
mpagenko7d6bb022021-03-11 15:07:55 +00002382 oFsm.isAwaitingResponse = true
2383 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002384 select {
Himani Chawla26e555c2020-08-31 12:30:20 +05302385 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenkodff5dda2020-08-28 11:52:01 +00002386 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00002387 // logger.Infow(ctx,"LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00002388 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second): //AS FOR THE OTHER OMCI FSM's
dbainbri4d3a0dc2020-12-02 00:33:42 +00002389 logger.Warnw(ctx, "UniVlanConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002390 oFsm.mutexIsAwaitingResponse.Lock()
2391 oFsm.isAwaitingResponse = false
2392 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002393 return fmt.Errorf("uniVlanConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002394 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05302395 if success {
mpagenkocf48e452021-04-23 09:23:00 +00002396 logger.Debugw(ctx, "UniVlanConfigFsm multi entity response received", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002397 oFsm.mutexIsAwaitingResponse.Lock()
2398 oFsm.isAwaitingResponse = false
2399 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002400 return nil
2401 }
mpagenko7d6bb022021-03-11 15:07:55 +00002402 // waiting was aborted (probably on external request)
mpagenkocf48e452021-04-23 09:23:00 +00002403 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002404 oFsm.mutexIsAwaitingResponse.Lock()
2405 oFsm.isAwaitingResponse = false
2406 oFsm.mutexIsAwaitingResponse.Unlock()
2407 return fmt.Errorf(cErrWaitAborted)
mpagenkodff5dda2020-08-28 11:52:01 +00002408 }
2409}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002410
mpagenko551a4d42020-12-08 18:09:20 +00002411func (oFsm *UniVlanConfigFsm) performSettingMulticastME(ctx context.Context, tpID uint8, multicastGemPortID uint16, vlanID uint32) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002412 logger.Debugw(ctx, "Setting Multicast MEs", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002413 "multicastGemPortID": multicastGemPortID, "vlanID": vlanID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002414 errCreateMOP := oFsm.performCreatingMulticastOperationProfile(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002415 if errCreateMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002416 logger.Errorw(ctx, "MulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002417 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002418 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002419 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMOP)
2420 }
2421
dbainbri4d3a0dc2020-12-02 00:33:42 +00002422 errSettingMOP := oFsm.performSettingMulticastOperationProfile(ctx, multicastGemPortID, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002423 if errSettingMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002424 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002425 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002426 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002427 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errSettingMOP)
2428 }
2429
dbainbri4d3a0dc2020-12-02 00:33:42 +00002430 errCreateMSCI := oFsm.performCreatingMulticastSubscriberConfigInfo(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002431 if errCreateMSCI != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002432 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002433 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002434 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002435 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMSCI)
2436 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002437 macBpCdEID, errMacBpCdEID := generateMcastANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo))
2438 if errMacBpCdEID != nil {
2439 logger.Errorw(ctx, "MulticastMacBridgePortConfigData entity id generation failed, aborting AniConfig FSM!",
2440 log.Fields{"device-id": oFsm.deviceID})
2441 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2442 return fmt.Errorf("generateMcastANISideMBPCDEID responseError %s, error %s", oFsm.deviceID, errMacBpCdEID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002443
Mahir Gunyel6781f962021-05-16 23:30:08 -07002444 }
2445 logger.Debugw(ctx, "UniVlanConfigFsm set macBpCdEID for mcast", log.Fields{
2446 "EntitytId": strconv.FormatInt(int64(macBpCdEID), 16), "macBpNo": oFsm.pOnuUniPort.macBpNo,
2447 "in state": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002448 meParams := me.ParamData{
Mahir Gunyel6781f962021-05-16 23:30:08 -07002449 EntityID: macBpCdEID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002450 Attributes: me.AttributeValueMap{
2451 "BridgeIdPointer": macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo),
2452 "PortNum": 0xf0, //fixed unique ANI side indication
2453 "TpType": 6, //MCGemIWTP
2454 "TpPointer": multicastGemPortID,
2455 },
2456 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002457 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002458 meInstance, err := oFsm.pOmciCC.sendCreateMBPConfigDataVar(context.TODO(),
2459 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true, oFsm.pAdaptFsm.commChan, meParams)
2460 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002461 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002462 logger.Errorw(ctx, "MBPConfigDataVar create failed, aborting AniConfig FSM!",
2463 log.Fields{"device-id": oFsm.deviceID})
2464 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2465 return fmt.Errorf("creatingMulticastSubscriberConfigInfo createError #{oFsm.deviceID}, error #{err}")
2466 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002467 //accept also nil as (error) return value for writing to LastTx
2468 // - this avoids misinterpretation of new received OMCI messages
2469 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002470 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002471 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002472 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002473 logger.Errorw(ctx, "CreateMBPConfigData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002474 log.Fields{"device-id": oFsm.deviceID, "MBPConfigDataID": macBridgeServiceProfileEID})
mpagenko9a304ea2020-12-16 15:54:01 +00002475 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002476 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, err)
2477 }
2478
2479 // ==> Start creating VTFD for mcast vlan
2480
2481 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
2482 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07002483 mcastVtfdID := macBpCdEID
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002484
dbainbri4d3a0dc2020-12-02 00:33:42 +00002485 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD for mcast", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002486 "EntitytId": strconv.FormatInt(int64(mcastVtfdID), 16), "mcastVlanID": vlanID,
2487 "in state": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
2488 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
2489
2490 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
2491 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
2492 // new vlan associated with a different TP.
2493 vtfdFilterList[0] = uint16(vlanID)
2494
2495 meParams = me.ParamData{
2496 EntityID: mcastVtfdID,
2497 Attributes: me.AttributeValueMap{
2498 "VlanFilterList": vtfdFilterList,
2499 "ForwardOperation": uint8(0x10), //VID investigation
2500 "NumberOfEntries": oFsm.numVlanFilterEntries,
2501 },
2502 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002503 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002504 meInstance, err = oFsm.pOmciCC.sendCreateVtfdVar(context.TODO(),
2505 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true, oFsm.pAdaptFsm.commChan, meParams)
2506 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002507 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002508 logger.Errorw(ctx, "CreateVtfdVar create failed, aborting UniVlanConfigFsm!",
2509 log.Fields{"device-id": oFsm.deviceID})
2510 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2511 return fmt.Errorf("createMcastVlanFilterData creationError %s, error %s", oFsm.deviceID, err)
2512 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002513 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002514 oFsm.mutexPLastTxMeInstance.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002515 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002516 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002517 logger.Errorw(ctx, "CreateMcastVlanFilterData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002518 log.Fields{"device-id": oFsm.deviceID, "mcastVtfdID": mcastVtfdID})
mpagenko9a304ea2020-12-16 15:54:01 +00002519 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002520 return fmt.Errorf("createMcastVlanFilterData responseError %s, error %s", oFsm.deviceID, err)
2521 }
2522
2523 return nil
2524}
2525
dbainbri4d3a0dc2020-12-02 00:33:42 +00002526func (oFsm *UniVlanConfigFsm) performCreatingMulticastSubscriberConfigInfo(ctx context.Context) error {
Mahir Gunyel6781f962021-05-16 23:30:08 -07002527 instID, err := generateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002528 if err != nil {
Mahir Gunyel6781f962021-05-16 23:30:08 -07002529 logger.Errorw(ctx, "error generrating me instance id",
2530 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002531 return err
2532 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002533 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastSubscriberConfigInfo",
2534 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002535 meParams := me.ParamData{
2536 EntityID: instID,
2537 Attributes: me.AttributeValueMap{
2538 "MeType": 0,
2539 //Direct reference to the Operation profile
2540 //TODO ANI side used on UNI side, not the clearest option.
ozgecanetsia5c88b762021-03-23 10:27:15 +03002541 "MulticastOperationsProfilePointer": instID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002542 },
2543 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002544 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002545 meInstance, err := oFsm.pOmciCC.sendCreateMulticastSubConfigInfoVar(context.TODO(),
2546 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002547 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002548 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002549 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002550 logger.Errorw(ctx, "CreateMulticastSubConfigInfoVar create failed, aborting UniVlanConfigFSM!",
2551 log.Fields{"device-id": oFsm.deviceID})
2552 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2553 return fmt.Errorf("creatingMulticastSubscriberConfigInfo interface creationError %s, error %s",
2554 oFsm.deviceID, err)
2555 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002556 //accept also nil as (error) return value for writing to LastTx
2557 // - this avoids misinterpretation of new received OMCI messages
2558 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002559 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002560 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002561 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002562 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002563 logger.Errorw(ctx, "CreateMulticastSubConfigInfo create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002564 log.Fields{"device-id": oFsm.deviceID, "MulticastSubConfigInfo": instID})
2565 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s", oFsm.deviceID)
2566 }
2567 return nil
2568}
2569
dbainbri4d3a0dc2020-12-02 00:33:42 +00002570func (oFsm *UniVlanConfigFsm) performCreatingMulticastOperationProfile(ctx context.Context) error {
ozgecanetsia5c88b762021-03-23 10:27:15 +03002571 instID, err := oFsm.pDeviceHandler.getUniPortMEEntityID(oFsm.pOnuUniPort.portNo)
2572 if err != nil {
2573 logger.Errorw(ctx, "error fetching uni port me instance",
2574 log.Fields{"device-id": oFsm.deviceID, "portNo": oFsm.pOnuUniPort.portNo})
2575 return err
2576 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002577 instID += macBridgePortAniBaseEID
2578 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastOperationProfile",
2579 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002580 meParams := me.ParamData{
2581 EntityID: instID,
2582 Attributes: me.AttributeValueMap{
2583 "IgmpVersion": 2,
2584 "IgmpFunction": 0,
2585 //0 means false
2586 "ImmediateLeave": 0,
2587 "Robustness": 2,
2588 "QuerierIp": 0,
2589 "QueryInterval": 125,
2590 "QuerierMaxResponseTime": 100,
2591 "LastMemberResponseTime": 10,
2592 //0 means false
2593 "UnauthorizedJoinBehaviour": 0,
2594 },
2595 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002596 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002597 meInstance, err := oFsm.pOmciCC.sendCreateMulticastOperationProfileVar(context.TODO(),
2598 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002599 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002600 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002601 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002602 logger.Errorw(ctx, "CreateMulticastOperationProfileVar create failed, aborting UniVlanConfigFsm!",
2603 log.Fields{"device-id": oFsm.deviceID})
2604 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2605 return fmt.Errorf("createMulticastOperationProfileVar responseError %s, error %s", oFsm.deviceID, err)
2606 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002607 //accept also nil as (error) return value for writing to LastTx
2608 // - this avoids misinterpretation of new received OMCI messages
2609 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002610 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002611 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03002612 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002613 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002614 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002615 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03002616 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002617 }
2618 return nil
2619}
2620
dbainbri4d3a0dc2020-12-02 00:33:42 +00002621func (oFsm *UniVlanConfigFsm) performSettingMulticastOperationProfile(ctx context.Context, multicastGemPortID uint16, vlanID uint32) error {
ozgecanetsia5c88b762021-03-23 10:27:15 +03002622 instID, err := oFsm.pDeviceHandler.getUniPortMEEntityID(oFsm.pOnuUniPort.portNo)
2623 if err != nil {
2624 logger.Errorw(ctx, "error fetching uni port me instance",
2625 log.Fields{"device-id": oFsm.deviceID, "portNo": oFsm.pOnuUniPort.portNo})
2626 return err
2627 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002628 instID += macBridgePortAniBaseEID
2629 logger.Debugw(ctx, "UniVlanConfigFsm set MulticastOperationProfile",
2630 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002631 //TODO check that this is correct
2632 // Table control
2633 //setCtrl = 1
2634 //rowPartId = 0
2635 //test = 0
2636 //rowKey = 0
2637 tableCtrlStr := "0100000000000000"
2638 tableCtrl := AsByteSlice(tableCtrlStr)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002639 dynamicAccessCL := make([]uint8, 24)
2640 copy(dynamicAccessCL, tableCtrl)
2641 //Multicast GemPortId
2642 binary.BigEndian.PutUint16(dynamicAccessCL[2:], multicastGemPortID)
2643 // python version waits for installation of flows, see line 723 onward of
2644 // brcm_openomci_onu_handler.py
2645 binary.BigEndian.PutUint16(dynamicAccessCL[4:], uint16(vlanID))
2646 //Source IP all to 0
2647 binary.BigEndian.PutUint32(dynamicAccessCL[6:], IPToInt32(net.IPv4(0, 0, 0, 0)))
2648 //TODO start and end are hardcoded, get from TP
2649 // Destination IP address start of range
2650 binary.BigEndian.PutUint32(dynamicAccessCL[10:], IPToInt32(net.IPv4(225, 0, 0, 0)))
2651 // Destination IP address end of range
2652 binary.BigEndian.PutUint32(dynamicAccessCL[14:], IPToInt32(net.IPv4(239, 255, 255, 255)))
2653 //imputed group bandwidth
2654 binary.BigEndian.PutUint16(dynamicAccessCL[18:], 0)
2655
2656 meParams := me.ParamData{
2657 EntityID: instID,
2658 Attributes: me.AttributeValueMap{
2659 "DynamicAccessControlListTable": dynamicAccessCL,
2660 },
2661 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002662 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002663 meInstance, err := oFsm.pOmciCC.sendSetMulticastOperationProfileVar(context.TODO(),
2664 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002665 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002666 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002667 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002668 logger.Errorw(ctx, "SetMulticastOperationProfileVar set failed, aborting UniVlanConfigFsm!",
2669 log.Fields{"device-id": oFsm.deviceID})
2670 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2671 return fmt.Errorf("setMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
2672 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002673 //accept also nil as (error) return value for writing to LastTx
2674 // - this avoids misinterpretation of new received OMCI messages
2675 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002676 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002677 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03002678 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002679 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002680 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002681 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03002682 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002683 }
2684 return nil
2685}
Girish Gowdra26a40922021-01-29 17:14:34 -08002686
2687// IsFlowRemovePending returns true if there are pending flows to remove, else false.
mpagenkobb47bc22021-04-20 13:29:09 +00002688func (oFsm *UniVlanConfigFsm) IsFlowRemovePending(aFlowDeleteChannel chan<- bool) bool {
2689 oFsm.mutexFlowParams.Lock()
2690 defer oFsm.mutexFlowParams.Unlock()
2691 if len(oFsm.uniRemoveFlowsSlice) > 0 {
2692 //flow removal is still ongoing/pending
2693 oFsm.signalOnFlowDelete = true
2694 oFsm.flowDeleteChannel = aFlowDeleteChannel
2695 return true
2696 }
2697 return false
Girish Gowdra26a40922021-01-29 17:14:34 -08002698}