blob: 89433d40891af3b8de2186b6073ae577b195da27 [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
mpagenkof1fc3862021-02-16 10:09:52 +000039 cWaitForCookieDeletion = 3 //seconds
mpagenkodff5dda2020-08-28 11:52:01 +000040 cDefaultDownstreamMode = 0
41 cDefaultTpid = 0x8100
mpagenko01e726e2020-10-23 09:45:29 +000042 cVtfdTableSize = 12 //as per G.988
43 cMaxAllowedFlows = cVtfdTableSize //which might be under discussion, for the moment connected to limit of VLAN's within VTFD
mpagenkodff5dda2020-08-28 11:52:01 +000044)
45
46const (
mpagenkof1fc3862021-02-16 10:09:52 +000047 // internal offsets for requestEvent according to definition in onu_device_entry::OnuDeviceEvent
48 cDeviceEventOffsetAddWithKvStore = 0 //OmciVlanFilterAddDone - OmciVlanFilterAddDone cannot use because of lint
49 cDeviceEventOffsetAddNoKvStore = OmciVlanFilterAddDoneNoKvStore - OmciVlanFilterAddDone
50 cDeviceEventOffsetRemoveWithKvStore = OmciVlanFilterRemDone - OmciVlanFilterAddDone
51 cDeviceEventOffsetRemoveNoKvStore = OmciVlanFilterRemDoneNoKvStore - OmciVlanFilterAddDone
52)
53
54const (
mpagenkodff5dda2020-08-28 11:52:01 +000055 // bit mask offsets for EVTOCD VlanTaggingOperationTable related to 32 bits (4 bytes)
56 cFilterPrioOffset = 28
57 cFilterVidOffset = 15
58 cFilterTpidOffset = 12
59 cFilterEtherTypeOffset = 0
60 cTreatTTROffset = 30
61 cTreatPrioOffset = 16
62 cTreatVidOffset = 3
63 cTreatTpidOffset = 0
64)
65const (
66 // byte offsets for EVTOCD VlanTaggingOperationTable related to overall 16 byte size with slice byte 0 as first Byte (MSB)
67 cFilterOuterOffset = 0
68 cFilterInnerOffset = 4
69 cTreatOuterOffset = 8
70 cTreatInnerOffset = 12
71)
72const (
73 // basic values used within EVTOCD VlanTaggingOperationTable in respect to their bitfields
74 cPrioIgnoreTag uint32 = 15
75 cPrioDefaultFilter uint32 = 14
76 cPrioDoNotFilter uint32 = 8
77 cDoNotFilterVid uint32 = 4096
78 cDoNotFilterTPID uint32 = 0
79 cDoNotFilterEtherType uint32 = 0
80 cDoNotAddPrio uint32 = 15
81 cCopyPrioFromInner uint32 = 8
Himani Chawla4d908332020-08-31 12:30:20 +053082 //cDontCarePrio uint32 = 0
mpagenkodff5dda2020-08-28 11:52:01 +000083 cDontCareVid uint32 = 0
84 cDontCareTpid uint32 = 0
85 cSetOutputTpidCopyDei uint32 = 4
86)
87
88const (
Holger Hildebrandt10d98192021-01-27 15:29:31 +000089 // events of config UNI port VLAN FSM
mpagenko535d6ef2021-02-26 13:15:34 +000090 vlanEvStart = "vlanEvStart"
91 vlanEvWaitTechProf = "vlanEvWaitTechProf"
92 vlanEvCancelOutstandingConfig = "vlanEvCancelOutstandingConfig"
93 vlanEvContinueConfig = "vlanEvContinueConfig"
94 vlanEvStartConfig = "vlanEvStartConfig"
95 vlanEvRxConfigVtfd = "vlanEvRxConfigVtfd"
96 vlanEvRxConfigEvtocd = "vlanEvRxConfigEvtocd"
97 vlanEvWaitTPIncr = "vlanEvWaitTPIncr"
98 vlanEvIncrFlowConfig = "vlanEvIncrFlowConfig"
99 vlanEvRenew = "vlanEvRenew"
100 vlanEvRemFlowConfig = "vlanEvRemFlowConfig"
101 vlanEvRemFlowDone = "vlanEvRemFlowDone"
102 vlanEvFlowDataRemoved = "vlanEvFlowDataRemoved"
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000103 //vlanEvTimeoutSimple = "vlanEvTimeoutSimple"
104 //vlanEvTimeoutMids = "vlanEvTimeoutMids"
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000105 vlanEvReset = "vlanEvReset"
106 vlanEvRestart = "vlanEvRestart"
107 vlanEvSkipOmciConfig = "vlanEvSkipOmciConfig"
108 vlanEvSkipIncFlowConfig = "vlanEvSkipIncFlowConfig"
mpagenkodff5dda2020-08-28 11:52:01 +0000109)
mpagenko01e726e2020-10-23 09:45:29 +0000110
mpagenkodff5dda2020-08-28 11:52:01 +0000111const (
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000112 // states of config UNI port VLAN FSM
mpagenkodff5dda2020-08-28 11:52:01 +0000113 vlanStDisabled = "vlanStDisabled"
114 vlanStStarting = "vlanStStarting"
115 vlanStWaitingTechProf = "vlanStWaitingTechProf"
116 vlanStConfigVtfd = "vlanStConfigVtfd"
117 vlanStConfigEvtocd = "vlanStConfigEvtocd"
118 vlanStConfigDone = "vlanStConfigDone"
mpagenko551a4d42020-12-08 18:09:20 +0000119 vlanStIncrFlowWaitTP = "vlanStIncrFlowWaitTP"
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000120 vlanStConfigIncrFlow = "vlanStConfigIncrFlow"
mpagenko01e726e2020-10-23 09:45:29 +0000121 vlanStRemoveFlow = "vlanStRemoveFlow"
mpagenkodff5dda2020-08-28 11:52:01 +0000122 vlanStCleanupDone = "vlanStCleanupDone"
123 vlanStResetting = "vlanStResetting"
124)
mpagenkof1fc3862021-02-16 10:09:52 +0000125const cVlanFsmIdleState = vlanStConfigDone // state where no OMCI activity is done (for a longer time)
126const cVlanFsmConfiguredState = vlanStConfigDone // state that indicates that at least some valid user related VLAN configuration should exist
mpagenkodff5dda2020-08-28 11:52:01 +0000127
mpagenko01e726e2020-10-23 09:45:29 +0000128type uniVlanRuleParams struct {
mpagenko551a4d42020-12-08 18:09:20 +0000129 TpID uint8 `json:"tp_id"`
mpagenko01e726e2020-10-23 09:45:29 +0000130 MatchVid uint32 `json:"match_vid"` //use uint32 types for allowing immediate bitshifting
131 MatchPcp uint32 `json:"match_pcp"`
132 TagsToRemove uint32 `json:"tags_to_remove"`
133 SetVid uint32 `json:"set_vid"`
134 SetPcp uint32 `json:"set_pcp"`
135}
136
137type uniVlanFlowParams struct {
138 CookieSlice []uint64 `json:"cookie_slice"`
139 VlanRuleParams uniVlanRuleParams `json:"vlan_rule_params"`
140}
141
142type uniRemoveVlanFlowParams struct {
143 cookie uint64 //just the last cookie valid for removal
144 vlanRuleParams uniVlanRuleParams
145}
146
mpagenkobb47bc22021-04-20 13:29:09 +0000147//UniVlanConfigFsm defines the structure for the state machine for configuration of the VLAN related setting via OMCI
148// builds upon 'VLAN rules' that are derived from multiple flows
mpagenkodff5dda2020-08-28 11:52:01 +0000149type UniVlanConfigFsm struct {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530150 pDeviceHandler *deviceHandler
mpagenko01e726e2020-10-23 09:45:29 +0000151 deviceID string
Himani Chawla6d2ae152020-09-02 13:11:20 +0530152 pOmciCC *omciCC
153 pOnuUniPort *onuUniPort
154 pUniTechProf *onuUniTechProf
155 pOnuDB *onuDeviceDB
mpagenkodff5dda2020-08-28 11:52:01 +0000156 requestEvent OnuDeviceEvent
157 omciMIdsResponseReceived chan bool //seperate channel needed for checking multiInstance OMCI message responses
158 pAdaptFsm *AdapterFsm
159 acceptIncrementalEvtoOption bool
mpagenko2418ab02020-11-12 12:58:06 +0000160 clearPersistency bool
mpagenko7d6bb022021-03-11 15:07:55 +0000161 isAwaitingResponse bool
162 mutexIsAwaitingResponse sync.RWMutex
mpagenko551a4d42020-12-08 18:09:20 +0000163 mutexFlowParams sync.RWMutex
mpagenkobb47bc22021-04-20 13:29:09 +0000164 chCookieDeleted chan bool //channel to indicate that a specific cookie (related to the active rule) was deleted
mpagenko9a304ea2020-12-16 15:54:01 +0000165 actualUniVlanConfigRule uniVlanRuleParams
mpagenko01e726e2020-10-23 09:45:29 +0000166 uniVlanFlowParamsSlice []uniVlanFlowParams
167 uniRemoveFlowsSlice []uniRemoveVlanFlowParams
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000168 numUniFlows uint8 // expected number of flows should be less than 12
169 configuredUniFlow uint8
mpagenko01e726e2020-10-23 09:45:29 +0000170 numRemoveFlows uint8
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000171 numVlanFilterEntries uint8
mpagenko01e726e2020-10-23 09:45:29 +0000172 vlanFilterList [cVtfdTableSize]uint16
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000173 evtocdID uint16
mpagenko01e726e2020-10-23 09:45:29 +0000174 pLastTxMeInstance *me.ManagedEntity
mpagenkofc4f56e2020-11-04 17:17:49 +0000175 requestEventOffset uint8
mpagenko551a4d42020-12-08 18:09:20 +0000176 TpIDWaitingFor uint8
mpagenkobb47bc22021-04-20 13:29:09 +0000177 signalOnFlowDelete bool
178 flowDeleteChannel chan<- bool
mpagenkof1fc3862021-02-16 10:09:52 +0000179 //cookie value that indicates that a rule to add is delayed by waiting for deletion of some other existing rule with the same cookie
180 delayNewRuleCookie uint64
mpagenkodff5dda2020-08-28 11:52:01 +0000181}
182
mpagenko01e726e2020-10-23 09:45:29 +0000183//NewUniVlanConfigFsm is the 'constructor' for the state machine to config the PON ANI ports
184// of ONU UNI ports via OMCI
dbainbri4d3a0dc2020-12-02 00:33:42 +0000185func NewUniVlanConfigFsm(ctx context.Context, apDeviceHandler *deviceHandler, apDevOmciCC *omciCC, apUniPort *onuUniPort,
mpagenko551a4d42020-12-08 18:09:20 +0000186 apUniTechProf *onuUniTechProf, apOnuDB *onuDeviceDB, aTechProfileID uint8,
mpagenko01e726e2020-10-23 09:45:29 +0000187 aRequestEvent OnuDeviceEvent, aName string, aCommChannel chan Message, aAcceptIncrementalEvto bool,
188 aCookieSlice []uint64, aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) *UniVlanConfigFsm {
mpagenkodff5dda2020-08-28 11:52:01 +0000189 instFsm := &UniVlanConfigFsm{
190 pDeviceHandler: apDeviceHandler,
mpagenko01e726e2020-10-23 09:45:29 +0000191 deviceID: apDeviceHandler.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +0000192 pOmciCC: apDevOmciCC,
193 pOnuUniPort: apUniPort,
194 pUniTechProf: apUniTechProf,
195 pOnuDB: apOnuDB,
mpagenkodff5dda2020-08-28 11:52:01 +0000196 requestEvent: aRequestEvent,
197 acceptIncrementalEvtoOption: aAcceptIncrementalEvto,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000198 numUniFlows: 0,
199 configuredUniFlow: 0,
mpagenko01e726e2020-10-23 09:45:29 +0000200 numRemoveFlows: 0,
mpagenko2418ab02020-11-12 12:58:06 +0000201 clearPersistency: true,
mpagenkodff5dda2020-08-28 11:52:01 +0000202 }
203
mpagenko01e726e2020-10-23 09:45:29 +0000204 instFsm.pAdaptFsm = NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
mpagenkodff5dda2020-08-28 11:52:01 +0000205 if instFsm.pAdaptFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000206 logger.Errorw(ctx, "UniVlanConfigFsm's AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000207 "device-id": instFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000208 return nil
209 }
mpagenkodff5dda2020-08-28 11:52:01 +0000210 instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
211 vlanStDisabled,
212 fsm.Events{
213 {Name: vlanEvStart, Src: []string{vlanStDisabled}, Dst: vlanStStarting},
214 {Name: vlanEvWaitTechProf, Src: []string{vlanStStarting}, Dst: vlanStWaitingTechProf},
mpagenko535d6ef2021-02-26 13:15:34 +0000215 {Name: vlanEvCancelOutstandingConfig, Src: []string{vlanStWaitingTechProf}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000216 {Name: vlanEvContinueConfig, Src: []string{vlanStWaitingTechProf}, Dst: vlanStConfigVtfd},
217 {Name: vlanEvStartConfig, Src: []string{vlanStStarting}, Dst: vlanStConfigVtfd},
218 {Name: vlanEvRxConfigVtfd, Src: []string{vlanStConfigVtfd}, Dst: vlanStConfigEvtocd},
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000219 {Name: vlanEvRxConfigEvtocd, Src: []string{vlanStConfigEvtocd, vlanStConfigIncrFlow},
220 Dst: vlanStConfigDone},
mpagenko551a4d42020-12-08 18:09:20 +0000221 {Name: vlanEvRenew, Src: []string{vlanStConfigDone}, Dst: vlanStStarting},
222 {Name: vlanEvWaitTPIncr, Src: []string{vlanStConfigDone}, Dst: vlanStIncrFlowWaitTP},
223 {Name: vlanEvIncrFlowConfig, Src: []string{vlanStConfigDone, vlanStIncrFlowWaitTP},
224 Dst: vlanStConfigIncrFlow},
mpagenko01e726e2020-10-23 09:45:29 +0000225 {Name: vlanEvRemFlowConfig, Src: []string{vlanStConfigDone}, Dst: vlanStRemoveFlow},
226 {Name: vlanEvRemFlowDone, Src: []string{vlanStRemoveFlow}, Dst: vlanStCleanupDone},
227 {Name: vlanEvFlowDataRemoved, Src: []string{vlanStCleanupDone}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000228 /*
229 {Name: vlanEvTimeoutSimple, Src: []string{
230 vlanStCreatingDot1PMapper, vlanStCreatingMBPCD, vlanStSettingTconts, vlanStSettingDot1PMapper}, Dst: vlanStStarting},
231 {Name: vlanEvTimeoutMids, Src: []string{
232 vlanStCreatingGemNCTPs, vlanStCreatingGemIWs, vlanStSettingPQs}, Dst: vlanStStarting},
233 */
234 // exceptional treatment for all states except vlanStResetting
235 {Name: vlanEvReset, Src: []string{vlanStStarting, vlanStWaitingTechProf,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000236 vlanStConfigVtfd, vlanStConfigEvtocd, vlanStConfigDone, vlanStConfigIncrFlow,
mpagenko01e726e2020-10-23 09:45:29 +0000237 vlanStRemoveFlow, vlanStCleanupDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000238 Dst: vlanStResetting},
239 // the only way to get to resource-cleared disabled state again is via "resseting"
240 {Name: vlanEvRestart, Src: []string{vlanStResetting}, Dst: vlanStDisabled},
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000241 // transitions for reconcile handling according to VOL-3834
242 {Name: vlanEvSkipOmciConfig, Src: []string{vlanStStarting}, Dst: vlanStConfigDone},
243 {Name: vlanEvSkipOmciConfig, Src: []string{vlanStConfigDone}, Dst: vlanStConfigIncrFlow},
244 {Name: vlanEvSkipIncFlowConfig, Src: []string{vlanStConfigIncrFlow}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000245 },
mpagenkodff5dda2020-08-28 11:52:01 +0000246 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000247 "enter_state": func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(ctx, e) },
248 "enter_" + vlanStStarting: func(e *fsm.Event) { instFsm.enterConfigStarting(ctx, e) },
249 "enter_" + vlanStConfigVtfd: func(e *fsm.Event) { instFsm.enterConfigVtfd(ctx, e) },
250 "enter_" + vlanStConfigEvtocd: func(e *fsm.Event) { instFsm.enterConfigEvtocd(ctx, e) },
251 "enter_" + vlanStConfigDone: func(e *fsm.Event) { instFsm.enterVlanConfigDone(ctx, e) },
252 "enter_" + vlanStConfigIncrFlow: func(e *fsm.Event) { instFsm.enterConfigIncrFlow(ctx, e) },
253 "enter_" + vlanStRemoveFlow: func(e *fsm.Event) { instFsm.enterRemoveFlow(ctx, e) },
254 "enter_" + vlanStCleanupDone: func(e *fsm.Event) { instFsm.enterVlanCleanupDone(ctx, e) },
255 "enter_" + vlanStResetting: func(e *fsm.Event) { instFsm.enterResetting(ctx, e) },
256 "enter_" + vlanStDisabled: func(e *fsm.Event) { instFsm.enterDisabled(ctx, e) },
mpagenkodff5dda2020-08-28 11:52:01 +0000257 },
258 )
259 if instFsm.pAdaptFsm.pFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000260 logger.Errorw(ctx, "UniVlanConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000261 "device-id": instFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000262 return nil
263 }
264
dbainbri4d3a0dc2020-12-02 00:33:42 +0000265 _ = instFsm.initUniFlowParams(ctx, aTechProfileID, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000266
dbainbri4d3a0dc2020-12-02 00:33:42 +0000267 logger.Debugw(ctx, "UniVlanConfigFsm created", log.Fields{"device-id": instFsm.deviceID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000268 "accIncrEvto": instFsm.acceptIncrementalEvtoOption})
mpagenkodff5dda2020-08-28 11:52:01 +0000269 return instFsm
270}
271
mpagenko01e726e2020-10-23 09:45:29 +0000272//initUniFlowParams is a simplified form of SetUniFlowParams() used for first flow parameters configuration
mpagenko551a4d42020-12-08 18:09:20 +0000273func (oFsm *UniVlanConfigFsm) initUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +0000274 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) error {
275 loRuleParams := uniVlanRuleParams{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000276 TpID: aTpID,
277 MatchVid: uint32(aMatchVlan),
278 SetVid: uint32(aSetVlan),
279 SetPcp: uint32(aSetPcp),
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000280 }
281 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
mpagenko01e726e2020-10-23 09:45:29 +0000282 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
283 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000284
mpagenko01e726e2020-10-23 09:45:29 +0000285 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000286 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000287 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000288 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
289 } else {
290 if !oFsm.acceptIncrementalEvtoOption {
291 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000292 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000293 }
294 }
295
mpagenko01e726e2020-10-23 09:45:29 +0000296 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000297 // no prio/vid filtering requested
mpagenko01e726e2020-10-23 09:45:29 +0000298 loRuleParams.TagsToRemove = 0 //no tag pop action
299 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
300 if loRuleParams.SetPcp == cCopyPrioFromInner {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000301 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
302 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
303 // might collide with NoMatchVid/CopyPrio(/setVid) setting
304 // this was some precondition setting taken over from py adapter ..
mpagenko01e726e2020-10-23 09:45:29 +0000305 loRuleParams.SetPcp = 0
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000306 }
307 }
mpagenko01e726e2020-10-23 09:45:29 +0000308
309 loFlowParams := uniVlanFlowParams{VlanRuleParams: loRuleParams}
310 loFlowParams.CookieSlice = make([]uint64, 0)
311 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
312
313 //no mutex protection is required for initial access and adding the first flow is always possible
314 oFsm.uniVlanFlowParamsSlice = make([]uniVlanFlowParams, 0)
315 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000316 logger.Debugw(ctx, "first UniVlanConfigFsm flow added", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000317 "Cookies": oFsm.uniVlanFlowParamsSlice[0].CookieSlice,
318 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
319 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
320 "SetPcp": loRuleParams.SetPcp,
321 "device-id": oFsm.deviceID})
322 oFsm.numUniFlows = 1
323 oFsm.uniRemoveFlowsSlice = make([]uniRemoveVlanFlowParams, 0) //initially nothing to remove
324
325 //permanently store flow config for reconcile case
dbainbri4d3a0dc2020-12-02 00:33:42 +0000326 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
mpagenkof1fc3862021-02-16 10:09:52 +0000327 &oFsm.uniVlanFlowParamsSlice, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000328 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000329 return err
330 }
331
332 return nil
333}
334
mpagenko7d6bb022021-03-11 15:07:55 +0000335//CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
mpagenko73143992021-04-09 15:17:10 +0000336func (oFsm *UniVlanConfigFsm) CancelProcessing(ctx context.Context) {
mpagenko7d6bb022021-03-11 15:07:55 +0000337 //mutex protection is required for possible concurrent access to FSM members
338 oFsm.mutexIsAwaitingResponse.RLock()
339 defer oFsm.mutexIsAwaitingResponse.RUnlock()
340 if oFsm.isAwaitingResponse {
341 //use channel to indicate that the response waiting shall be aborted
342 oFsm.omciMIdsResponseReceived <- false
343 }
344 // in any case (even if it might be automatically requested by above cancellation of waiting) ensure resetting the FSM
345 pAdaptFsm := oFsm.pAdaptFsm
346 if pAdaptFsm != nil {
mpagenkobb47bc22021-04-20 13:29:09 +0000347 if fsmErr := pAdaptFsm.pFsm.Event(vlanEvReset); fsmErr != nil {
348 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
349 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000350 }
mpagenko7d6bb022021-03-11 15:07:55 +0000351 }
352}
353
mpagenko551a4d42020-12-08 18:09:20 +0000354//GetWaitingTpID returns the TpId that the FSM might be waiting for continuation (0 if none)
355func (oFsm *UniVlanConfigFsm) GetWaitingTpID() uint8 {
356 //mutex protection is required for possible concurrent access to FSM members
357 oFsm.mutexFlowParams.RLock()
358 defer oFsm.mutexFlowParams.RUnlock()
359 return oFsm.TpIDWaitingFor
360}
361
mpagenko2418ab02020-11-12 12:58:06 +0000362//RequestClearPersistency sets the internal flag to not clear persistency data (false=NoClear)
363func (oFsm *UniVlanConfigFsm) RequestClearPersistency(aClear bool) {
364 //mutex protection is required for possible concurrent access to FSM members
mpagenko15ff4a52021-03-02 10:09:20 +0000365 oFsm.mutexFlowParams.Lock()
366 defer oFsm.mutexFlowParams.Unlock()
mpagenko2418ab02020-11-12 12:58:06 +0000367 oFsm.clearPersistency = aClear
368}
369
mpagenko01e726e2020-10-23 09:45:29 +0000370//SetUniFlowParams verifies on existence of flow parameters to be configured,
371// optionally udates the cookie list or appends a new flow if there is space
372// if possible the FSM is trigggerd to start with the processing
mpagenko551a4d42020-12-08 18:09:20 +0000373// ignore complexity by now
374// nolint: gocyclo
375func (oFsm *UniVlanConfigFsm) SetUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +0000376 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) error {
377 loRuleParams := uniVlanRuleParams{
378 TpID: aTpID,
379 MatchVid: uint32(aMatchVlan),
380 SetVid: uint32(aSetVlan),
381 SetPcp: uint32(aSetPcp),
382 }
383 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
384 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
385 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
386
387 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
388 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
389 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
390 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
391 } else {
392 if !oFsm.acceptIncrementalEvtoOption {
393 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
394 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
395 }
396 }
397
398 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
399 // no prio/vid filtering requested
400 loRuleParams.TagsToRemove = 0 //no tag pop action
401 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
402 if loRuleParams.SetPcp == cCopyPrioFromInner {
403 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
404 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
405 // might collide with NoMatchVid/CopyPrio(/setVid) setting
406 // this was some precondition setting taken over from py adapter ..
407 loRuleParams.SetPcp = 0
408 }
409 }
410
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000411 flowEntryMatch := false
mpagenko01e726e2020-10-23 09:45:29 +0000412 flowCookieModify := false
mpagenkof1fc3862021-02-16 10:09:52 +0000413 requestAppendRule := false
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000414 //mutex protection is required for possible concurrent access to FSM members
415 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +0000416 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
417 //TODO: Verify if using e.g. hashes for the structures here for comparison may generate
418 // countable run time optimization (perhaps with including the hash in kvStore storage?)
419 if storedUniFlowParams.VlanRuleParams == loRuleParams {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000420 flowEntryMatch = true
dbainbri4d3a0dc2020-12-02 00:33:42 +0000421 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - rule already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000422 "device-id": oFsm.deviceID})
423 var cookieMatch bool
424 for _, newCookie := range aCookieSlice { // for all cookies available in the arguments
425 cookieMatch = false
426 for _, cookie := range storedUniFlowParams.CookieSlice {
427 if cookie == newCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000428 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - and cookie already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000429 "device-id": oFsm.deviceID, "cookie": cookie})
430 cookieMatch = true
431 break //found new cookie - no further search for this requested cookie
432 }
433 }
434 if !cookieMatch {
mpagenkof1fc3862021-02-16 10:09:52 +0000435 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
436 if delayedCookie != 0 {
437 //a delay for adding the cookie to this rule is requested
438 // take care of the mutex which is already locked here, need to unlock/lock accordingly to prevent deadlock in suspension
439 oFsm.mutexFlowParams.Unlock()
440 oFsm.suspendNewRule(ctx)
441 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
442 oFsm.mutexFlowParams.Lock()
443 } else {
444 logger.Debugw(ctx, "UniVlanConfigFsm flow setting -adding new cookie", log.Fields{
445 "device-id": oFsm.deviceID, "cookie": newCookie})
446 //as range works with copies of the slice we have to write to the original slice!!
447 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
448 newCookie)
449 flowCookieModify = true
450 }
mpagenko01e726e2020-10-23 09:45:29 +0000451 }
452 } //for all new cookies
453 break // found rule - no further rule search
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000454 }
455 }
mpagenkof1fc3862021-02-16 10:09:52 +0000456 oFsm.mutexFlowParams.Unlock()
457
458 if !flowEntryMatch { //it is (was) a new rule
459 delayedCookie := oFsm.suspendIfRequiredNewRule(ctx, aCookieSlice)
460 requestAppendRule = true //default assumption here is that rule is to be appended
461 flowCookieModify = true //and that the the flow data base is to be updated
462 if delayedCookie != 0 { //it was suspended
463 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
464 }
465 }
466 kvStoreWrite := false //default setting is to not write to kvStore immediately - will be done on FSM execution finally
467 if requestAppendRule {
468 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000469 if oFsm.numUniFlows < cMaxAllowedFlows {
mpagenko01e726e2020-10-23 09:45:29 +0000470 loFlowParams := uniVlanFlowParams{VlanRuleParams: loRuleParams}
471 loFlowParams.CookieSlice = make([]uint64, 0)
472 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
473 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000474 logger.Debugw(ctx, "UniVlanConfigFsm flow add", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000475 "Cookies": oFsm.uniVlanFlowParamsSlice[oFsm.numUniFlows].CookieSlice,
476 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
477 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
Girish Gowdra041dcb32020-11-16 16:54:30 -0800478 "SetPcp": loRuleParams.SetPcp, "numberofFlows": oFsm.numUniFlows + 1,
mpagenko01e726e2020-10-23 09:45:29 +0000479 "device-id": oFsm.deviceID})
480
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000481 oFsm.numUniFlows++
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000482 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
483
484 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
485 logger.Debugw(ctx, "reconciling - skip omci-config of additional vlan rule",
486 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
mpagenkobb47bc22021-04-20 13:29:09 +0000487 //attention: take care to release the mutexFlowParams when calling the FSM directly -
488 // synchronous FSM 'event/state' functions may rely on this mutex
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000489 oFsm.mutexFlowParams.Unlock()
490 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
mpagenkobb47bc22021-04-20 13:29:09 +0000491 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvSkipOmciConfig); fsmErr != nil {
492 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
493 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
494 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000495 }
496 return nil
497 }
mpagenko01e726e2020-10-23 09:45:29 +0000498 // note: theoretical it would be possible to clear the same rule from the remove slice
499 // (for entries that have not yet been started with removal)
500 // but that is getting quite complicated - maybe a future optimization in case it should prove reasonable
501 // 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 +0000502
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000503 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
504 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
mpagenko551a4d42020-12-08 18:09:20 +0000505 if oFsm.configuredUniFlow == 0 {
506 // this is a restart with a complete new flow, we can re-use the initial flow config control
507 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenkobb47bc22021-04-20 13:29:09 +0000508 //attention: take care to release the mutexFlowParams when calling the FSM directly -
509 // synchronous FSM 'event/state' functions may rely on this mutex
510 oFsm.mutexFlowParams.Unlock()
511 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvRenew); fsmErr != nil {
512 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
513 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
514 }
mpagenko551a4d42020-12-08 18:09:20 +0000515 } else {
516 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000517 //store the actual rule that shall be worked upon in the following transient states
518 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +0000519 //tpId of the next rule to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000520 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko551a4d42020-12-08 18:09:20 +0000521 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, tpID)
522 oFsm.TpIDWaitingFor = tpID
mpagenko9a304ea2020-12-16 15:54:01 +0000523 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request (on setConfig)", log.Fields{
524 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
525 "set-Vlan": oFsm.actualUniVlanConfigRule.SetVid, "tp-id": tpID, "ProfDone": loTechProfDone})
mpagenkobb47bc22021-04-20 13:29:09 +0000526
527 //attention: take care to release the mutexFlowParams when calling the FSM directly -
528 // synchronous FSM 'event/state' functions may rely on this mutex
529 oFsm.mutexFlowParams.Unlock()
530 var fsmErr error
531 if loTechProfDone {
532 // let the vlan processing continue with next rule
533 fsmErr = pConfigVlanStateBaseFsm.Event(vlanEvIncrFlowConfig)
534 } else {
535 // set to waiting for Techprofile
536 fsmErr = pConfigVlanStateBaseFsm.Event(vlanEvWaitTPIncr)
537 }
538 if fsmErr != nil {
539 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
540 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
541 }
mpagenko551a4d42020-12-08 18:09:20 +0000542 }
mpagenkobb47bc22021-04-20 13:29:09 +0000543 } else {
544 // if not in the appropriate state a new entry will be automatically considered later
545 // when the configDone state is reached
546 oFsm.mutexFlowParams.Unlock()
547 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000548 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000549 logger.Errorw(ctx, "UniVlanConfigFsm flow limit exceeded", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000550 "device-id": oFsm.deviceID, "flow-number": oFsm.numUniFlows})
mpagenko15ff4a52021-03-02 10:09:20 +0000551 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000552 return fmt.Errorf(" UniVlanConfigFsm flow limit exceeded %s", oFsm.deviceID)
553 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000554 } else {
555 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
mpagenkof1fc3862021-02-16 10:09:52 +0000556 kvStoreWrite = true // ensure actual data write to kvStore immediately (no FSM activity)
mpagenko15ff4a52021-03-02 10:09:20 +0000557 oFsm.mutexFlowParams.RLock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000558 if oFsm.numUniFlows == oFsm.configuredUniFlow {
559 //all requested rules really have been configured
560 // state transition notification is checked in deviceHandler
mpagenko15ff4a52021-03-02 10:09:20 +0000561 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000562 if oFsm.pDeviceHandler != nil {
563 //also the related TechProfile was already configured
dbainbri4d3a0dc2020-12-02 00:33:42 +0000564 logger.Debugw(ctx, "UniVlanConfigFsm rule already set - send immediate add-success event for reason update", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +0000565 "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +0000566 // success indication without the need to write to kvStore (done already below with updated data from storePersUniFlowConfig())
567 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetAddNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000568 }
569 } else {
570 // avoid device reason update as the rule config connected to this flow may still be in progress
571 // and the device reason should only be updated on success of rule config
dbainbri4d3a0dc2020-12-02 00:33:42 +0000572 logger.Debugw(ctx, "UniVlanConfigFsm rule already set but configuration ongoing, suppress early add-success event for reason update",
mpagenkofc4f56e2020-11-04 17:17:49 +0000573 log.Fields{"device-id": oFsm.deviceID,
574 "NumberofRules": oFsm.numUniFlows, "Configured rules": oFsm.configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +0000575 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000576 }
577 }
mpagenko01e726e2020-10-23 09:45:29 +0000578
mpagenkof1fc3862021-02-16 10:09:52 +0000579 if flowCookieModify { // some change was done to the flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000580 //permanently store flow config for reconcile case
mpagenko15ff4a52021-03-02 10:09:20 +0000581 oFsm.mutexFlowParams.RLock()
mpagenkof1fc3862021-02-16 10:09:52 +0000582 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
583 &oFsm.uniVlanFlowParamsSlice, kvStoreWrite); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +0000584 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000585 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000586 return err
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000587 }
mpagenko15ff4a52021-03-02 10:09:20 +0000588 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000589 }
590 return nil
591}
592
mpagenkof1fc3862021-02-16 10:09:52 +0000593// VOL-3828 flow config sequence workaround ########### start ##########
594func (oFsm *UniVlanConfigFsm) delayNewRuleForCookie(ctx context.Context, aCookieSlice []uint64) uint64 {
595 //assumes mutexFlowParams.Lock() protection from caller!
596 if oFsm.delayNewRuleCookie == 0 && len(aCookieSlice) == 1 {
597 // if not already waiting, limitation for this workaround is to just have one overlapping cookie/rule
598 // suspend check is done only of there is only one cookie in the request
599 // background: more elements only expected in reconcile use case, where no conflicting sequence is to be expected
600 newCookie := aCookieSlice[0]
601 for _, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
602 for _, cookie := range storedUniFlowParams.CookieSlice {
603 if cookie == newCookie {
604 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - new cookie still exists for some rule", log.Fields{
605 "device-id": oFsm.deviceID, "cookie": cookie, "exists with SetVlan": storedUniFlowParams.VlanRuleParams.SetVid})
606 oFsm.delayNewRuleCookie = newCookie
607 return newCookie //found new cookie in some existing rule
608 }
609 } // for all stored cookies of the actual inspected rule
610 } //for all rules
611 }
612 return 0 //no delay requested
613}
614func (oFsm *UniVlanConfigFsm) suspendNewRule(ctx context.Context) {
615 oFsm.mutexFlowParams.RLock()
616 logger.Infow(ctx, "Need to suspend adding this rule as long as the cookie is still connected to some other rule", log.Fields{
617 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
618 oFsm.mutexFlowParams.RUnlock()
619 select {
620 case <-oFsm.chCookieDeleted:
621 logger.Infow(ctx, "resume adding this rule after having deleted cookie in some other rule", log.Fields{
622 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
623 case <-time.After(time.Duration(cWaitForCookieDeletion) * time.Second):
624 logger.Errorw(ctx, "timeout waiting for deletion of cookie in some other rule, just try to continue", log.Fields{
625 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
626 }
627 oFsm.mutexFlowParams.Lock()
628 oFsm.delayNewRuleCookie = 0
629 oFsm.mutexFlowParams.Unlock()
630}
631func (oFsm *UniVlanConfigFsm) suspendIfRequiredNewRule(ctx context.Context, aCookieSlice []uint64) uint64 {
632 oFsm.mutexFlowParams.Lock()
633 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
634 oFsm.mutexFlowParams.Unlock()
635
636 if delayedCookie != 0 {
637 oFsm.suspendNewRule(ctx)
638 }
639 return delayedCookie
640}
641
642//returns flowModified, RuleAppendRequest
643func (oFsm *UniVlanConfigFsm) reviseFlowConstellation(ctx context.Context, aCookie uint64, aUniVlanRuleParams uniVlanRuleParams) (bool, bool) {
644 flowEntryMatch := false
645 oFsm.mutexFlowParams.Lock()
646 defer oFsm.mutexFlowParams.Unlock()
647 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
648 if storedUniFlowParams.VlanRuleParams == aUniVlanRuleParams {
649 flowEntryMatch = true
650 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - rule already exists", log.Fields{
651 "device-id": oFsm.deviceID})
652 cookieMatch := false
653 for _, cookie := range storedUniFlowParams.CookieSlice {
654 if cookie == aCookie {
655 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - and cookie already exists", log.Fields{
656 "device-id": oFsm.deviceID, "cookie": cookie})
657 cookieMatch = true
658 break //found new cookie - no further search for this requested cookie
659 }
660 }
661 if !cookieMatch {
662 logger.Debugw(ctx, "UniVlanConfigFsm flow revise -adding new cookie", log.Fields{
663 "device-id": oFsm.deviceID, "cookie": aCookie})
664 //as range works with copies of the slice we have to write to the original slice!!
665 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
666 aCookie)
667 return true, false //flowModified, NoRuleAppend
668 }
669 break // found rule - no further rule search
670 }
671 }
672 if !flowEntryMatch { //it is a new rule
673 return true, true //flowModified, RuleAppend
674 }
675 return false, false //flowNotModified, NoRuleAppend
676}
677
678// VOL-3828 flow config sequence workaround ########### end ##########
679
mpagenko01e726e2020-10-23 09:45:29 +0000680//RemoveUniFlowParams verifies on existence of flow cookie,
681// if found removes cookie from flow cookie list and if this is empty
682// initiates removal of the flow related configuration from the ONU (via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000683func (oFsm *UniVlanConfigFsm) RemoveUniFlowParams(ctx context.Context, aCookie uint64) error {
mpagenkof1fc3862021-02-16 10:09:52 +0000684 var deletedCookie uint64
mpagenko01e726e2020-10-23 09:45:29 +0000685 flowCookieMatch := false
686 //mutex protection is required for possible concurrent access to FSM members
687 oFsm.mutexFlowParams.Lock()
688 defer oFsm.mutexFlowParams.Unlock()
mpagenkof1fc3862021-02-16 10:09:52 +0000689remove_loop:
mpagenko01e726e2020-10-23 09:45:29 +0000690 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
691 for i, cookie := range storedUniFlowParams.CookieSlice {
692 if cookie == aCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000693 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - cookie found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000694 "device-id": oFsm.deviceID, "cookie": cookie})
695 flowCookieMatch = true
mpagenkof1fc3862021-02-16 10:09:52 +0000696 deletedCookie = aCookie
697 kvStoreWrite := false //default setting is to not write to kvStore immediately - will be done on FSM execution finally
mpagenko01e726e2020-10-23 09:45:29 +0000698 //remove the cookie from the cookie slice and verify it is getting empty
699 if len(storedUniFlowParams.CookieSlice) == 1 {
mpagenko535d6ef2021-02-26 13:15:34 +0000700 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
701 var cancelPendingConfig bool = false
702 var loRemoveParams uniRemoveVlanFlowParams = uniRemoveVlanFlowParams{}
dbainbri4d3a0dc2020-12-02 00:33:42 +0000703 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - full flow removal", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000704 "device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +0000705 //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 +0000706 // as the one still waiting in the FSM as toAdd but waiting for TechProfileConfig
mpagenko15ff4a52021-03-02 10:09:20 +0000707 // 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 +0000708 // if the Fsm is in some other transient (config) state, we will reach the DelRequest later and correctly process it then
709 if pConfigVlanStateBaseFsm.Is(vlanStWaitingTechProf) {
710 logger.Debugw(ctx, "UniVlanConfigFsm was waiting for TechProf config with this rule, aborting the outstanding config",
711 log.Fields{"device-id": oFsm.deviceID})
712 cancelPendingConfig = true
713 } else {
714 //create a new element for the removeVlanFlow slice
715 loRemoveParams = uniRemoveVlanFlowParams{
716 vlanRuleParams: storedUniFlowParams.VlanRuleParams,
717 cookie: aCookie,
718 }
719 oFsm.uniRemoveFlowsSlice = append(oFsm.uniRemoveFlowsSlice, loRemoveParams)
mpagenko01e726e2020-10-23 09:45:29 +0000720 }
mpagenko01e726e2020-10-23 09:45:29 +0000721
722 //and remove the actual element from the addVlanFlow slice
723 // oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = nil //automatically done by garbage collector
724 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
725 oFsm.numUniFlows = 0 //no more flows
726 oFsm.configuredUniFlow = 0 //no more flows configured
727 oFsm.uniVlanFlowParamsSlice = nil //reset the slice
mpagenko2418ab02020-11-12 12:58:06 +0000728 //at this point it is evident that no flow anymore refers to a still possibly active Techprofile
mpagenko535d6ef2021-02-26 13:15:34 +0000729 //request that this profile gets deleted before a new flow add is allowed (except for some aborted add)
730 if !cancelPendingConfig {
731 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, loRemoveParams.vlanRuleParams.TpID, true)
732 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000733 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - no more flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000734 "device-id": oFsm.deviceID})
735 } else {
736 oFsm.numUniFlows--
737 if oFsm.configuredUniFlow > 0 {
738 oFsm.configuredUniFlow--
739 //TODO!! might be needed to consider still outstanding configure requests ..
740 // so a flow at removal might still not be configured !?!
741 }
mpagenko2418ab02020-11-12 12:58:06 +0000742 usedTpID := storedUniFlowParams.VlanRuleParams.TpID
mpagenko01e726e2020-10-23 09:45:29 +0000743 //cut off the requested flow by slicing out this element
744 oFsm.uniVlanFlowParamsSlice = append(
745 oFsm.uniVlanFlowParamsSlice[:flow], oFsm.uniVlanFlowParamsSlice[flow+1:]...)
mpagenko2418ab02020-11-12 12:58:06 +0000746 //here we have to check, if there are still other flows referencing to the actual ProfileId
747 // before we can request that this profile gets deleted before a new flow add is allowed
mpagenkof1fc3862021-02-16 10:09:52 +0000748 // (needed to extract to function due to lint complexity)
mpagenko535d6ef2021-02-26 13:15:34 +0000749 if !cancelPendingConfig {
750 oFsm.updateTechProfileToDelete(ctx, usedTpID)
751 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000752 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow removed from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000753 "device-id": oFsm.deviceID})
754 }
755 //trigger the FSM to remove the relevant rule
mpagenko535d6ef2021-02-26 13:15:34 +0000756 if cancelPendingConfig {
757 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
mpagenkobb47bc22021-04-20 13:29:09 +0000758 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
759 // synchronous FSM 'event/state' functions may rely on this mutex
760 oFsm.mutexFlowParams.Unlock()
761 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvCancelOutstandingConfig); fsmErr != nil {
762 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
763 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
764 }
765 oFsm.mutexFlowParams.Lock()
mpagenko535d6ef2021-02-26 13:15:34 +0000766 } else {
767 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
768 logger.Debugw(ctx, "UniVlanConfigFsm rule removal request", log.Fields{
769 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
770 "tp-id": loRemoveParams.vlanRuleParams.TpID,
771 "set-Vlan": loRemoveParams.vlanRuleParams.SetVid})
772 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
mpagenkobb47bc22021-04-20 13:29:09 +0000773 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
774 // synchronous FSM 'event/state' functions may rely on this mutex
775 oFsm.mutexFlowParams.Unlock()
776 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvRemFlowConfig); fsmErr != nil {
777 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
778 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
779 }
780 oFsm.mutexFlowParams.Lock()
mpagenko535d6ef2021-02-26 13:15:34 +0000781 } // if not in the appropriate state a new entry will be automatically considered later
782 // when the configDone state is reached
783 }
mpagenko01e726e2020-10-23 09:45:29 +0000784 } else {
mpagenko01e726e2020-10-23 09:45:29 +0000785 //cut off the requested cookie by slicing out this element
786 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(
787 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[:i],
788 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[i+1:]...)
mpagenkofc4f56e2020-11-04 17:17:49 +0000789 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
mpagenkof1fc3862021-02-16 10:09:52 +0000790 kvStoreWrite = true // ensure actual data write to kvStore immediately (no FSM activity)
mpagenkofc4f56e2020-11-04 17:17:49 +0000791 // state transition notification is checked in deviceHandler
792 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000793 // success indication without the need to write to kvStore (done already below with updated data from storePersUniFlowConfig())
794 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000795 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000796 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - rule persists with still valid cookies", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000797 "device-id": oFsm.deviceID, "cookies": oFsm.uniVlanFlowParamsSlice[flow].CookieSlice})
mpagenkof1fc3862021-02-16 10:09:52 +0000798 if deletedCookie == oFsm.delayNewRuleCookie {
799 //the delayedNewCookie is the one that is currently deleted, but the rule still exist with other cookies
800 //as long as there are further cookies for this rule indicate there is still some cookie to be deleted
801 //simply use the first one
802 oFsm.delayNewRuleCookie = oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[0]
803 logger.Debugw(ctx, "UniVlanConfigFsm remaining cookie awaited for deletion before new rule add", log.Fields{
804 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
805 }
mpagenko01e726e2020-10-23 09:45:29 +0000806 }
mpagenko01e726e2020-10-23 09:45:29 +0000807 //permanently store the modified flow config for reconcile case
mpagenkofc4f56e2020-11-04 17:17:49 +0000808 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000809 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
810 &oFsm.uniVlanFlowParamsSlice, kvStoreWrite); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000811 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +0000812 return err
813 }
mpagenko01e726e2020-10-23 09:45:29 +0000814 }
mpagenkof1fc3862021-02-16 10:09:52 +0000815 break remove_loop //found the cookie - no further search for this requested cookie
mpagenko01e726e2020-10-23 09:45:29 +0000816 }
817 }
mpagenko01e726e2020-10-23 09:45:29 +0000818 } //search all flows
819 if !flowCookieMatch { //some cookie remove-request for a cookie that does not exist in the FSM data
dbainbri4d3a0dc2020-12-02 00:33:42 +0000820 logger.Warnw(ctx, "UniVlanConfigFsm flow removal - remove-cookie not found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000821 "device-id": oFsm.deviceID, "remove-cookie": aCookie})
822 // but accept the request with success as no such cookie (flow) does exist
mpagenkofc4f56e2020-11-04 17:17:49 +0000823 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
824 // state transition notification is checked in deviceHandler
825 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000826 // success indication without the need to write to kvStore (no change)
827 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000828 }
mpagenko01e726e2020-10-23 09:45:29 +0000829 return nil
830 } //unknown cookie
831
832 return nil
833}
834
mpagenkof1fc3862021-02-16 10:09:52 +0000835func (oFsm *UniVlanConfigFsm) updateTechProfileToDelete(ctx context.Context, usedTpID uint8) {
836 //here we have to check, if there are still other flows referencing to the actual ProfileId
837 // before we can request that this profile gets deleted before a new flow add is allowed
838 tpIDInOtherFlows := false
839 for _, tpUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
840 if tpUniFlowParams.VlanRuleParams.TpID == usedTpID {
841 tpIDInOtherFlows = true
842 break // search loop can be left
843 }
844 }
845 if tpIDInOtherFlows {
846 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is still used in other flows", log.Fields{
847 "device-id": oFsm.deviceID, "tp-id": usedTpID})
848 } else {
849 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is not used anymore", log.Fields{
850 "device-id": oFsm.deviceID, "tp-id": usedTpID})
851 //request that this profile gets deleted before a new flow add is allowed
852 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, usedTpID, true)
853 }
854}
855
dbainbri4d3a0dc2020-12-02 00:33:42 +0000856func (oFsm *UniVlanConfigFsm) enterConfigStarting(ctx context.Context, e *fsm.Event) {
857 logger.Debugw(ctx, "UniVlanConfigFsm start", log.Fields{"in state": e.FSM.Current(),
mpagenko01e726e2020-10-23 09:45:29 +0000858 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000859
860 // this FSM is not intended for re-start, needs always new creation for a new run
mpagenko01e726e2020-10-23 09:45:29 +0000861 // (self-destroying - compare enterDisabled())
mpagenkodff5dda2020-08-28 11:52:01 +0000862 oFsm.omciMIdsResponseReceived = make(chan bool)
mpagenkof1fc3862021-02-16 10:09:52 +0000863 oFsm.chCookieDeleted = make(chan bool)
mpagenkodff5dda2020-08-28 11:52:01 +0000864 // start go routine for processing of LockState messages
dbainbri4d3a0dc2020-12-02 00:33:42 +0000865 go oFsm.processOmciVlanMessages(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +0000866 //let the state machine run forward from here directly
867 pConfigVlanStateAFsm := oFsm.pAdaptFsm
868 if pConfigVlanStateAFsm != nil {
mpagenko9a304ea2020-12-16 15:54:01 +0000869
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000870 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
871 logger.Debugw(ctx, "reconciling - skip omci-config of vlan rule",
872 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
873 go func(a_pAFsm *AdapterFsm) {
874 _ = a_pAFsm.pFsm.Event(vlanEvSkipOmciConfig)
875 }(pConfigVlanStateAFsm)
876 return
877 }
878 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +0000879 //possibly the entry is not valid anymore based on intermediate delete requests
880 //just a basic protection ...
881 if len(oFsm.uniVlanFlowParamsSlice) == 0 {
882 oFsm.mutexFlowParams.Unlock()
883 logger.Debugw(ctx, "UniVlanConfigFsm start: no rule entry anymore available", log.Fields{
884 "device-id": oFsm.deviceID})
885 // Can't call FSM Event directly, decoupling it
886 go func(a_pAFsm *AdapterFsm) {
887 _ = a_pAFsm.pFsm.Event(vlanEvReset)
888 }(pConfigVlanStateAFsm)
889 return
890 }
mpagenko9a304ea2020-12-16 15:54:01 +0000891 //access to uniVlanFlowParamsSlice is done on first element only here per definition
892 //store the actual rule that shall be worked upon in the following transient states
893 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[0].VlanRuleParams
mpagenko9a304ea2020-12-16 15:54:01 +0000894 tpID := oFsm.actualUniVlanConfigRule.TpID
895 oFsm.TpIDWaitingFor = tpID
mpagenko551a4d42020-12-08 18:09:20 +0000896 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID))
mpagenko9a304ea2020-12-16 15:54:01 +0000897 logger.Debugw(ctx, "UniVlanConfigFsm - start with first rule", log.Fields{
898 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
899 "set-Vlan": oFsm.actualUniVlanConfigRule.SetVid, "tp-id": tpID, "ProfDone": loTechProfDone})
mpagenko551a4d42020-12-08 18:09:20 +0000900 //cmp also usage in EVTOCDE create in omci_cc
901 oFsm.evtocdID = macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo)
mpagenko535d6ef2021-02-26 13:15:34 +0000902 oFsm.mutexFlowParams.Unlock()
mpagenko9a304ea2020-12-16 15:54:01 +0000903 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +0000904 go func(aPAFsm *AdapterFsm, aTechProfDone bool) {
905 if aPAFsm != nil && aPAFsm.pFsm != nil {
906 if aTechProfDone {
mpagenkodff5dda2020-08-28 11:52:01 +0000907 // let the vlan processing begin
mpagenko551a4d42020-12-08 18:09:20 +0000908 _ = aPAFsm.pFsm.Event(vlanEvStartConfig)
mpagenkodff5dda2020-08-28 11:52:01 +0000909 } else {
910 // set to waiting for Techprofile
mpagenko551a4d42020-12-08 18:09:20 +0000911 _ = aPAFsm.pFsm.Event(vlanEvWaitTechProf)
mpagenkodff5dda2020-08-28 11:52:01 +0000912 }
913 }
mpagenko551a4d42020-12-08 18:09:20 +0000914 }(pConfigVlanStateAFsm, loTechProfDone)
915 } else {
916 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
917 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
918 //should never happen, else: recovery would be needed from outside the FSM
919 return
mpagenkodff5dda2020-08-28 11:52:01 +0000920 }
921}
922
dbainbri4d3a0dc2020-12-02 00:33:42 +0000923func (oFsm *UniVlanConfigFsm) enterConfigVtfd(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000924 //mutex protection is required for possible concurrent access to FSM members
925 oFsm.mutexFlowParams.Lock()
mpagenko551a4d42020-12-08 18:09:20 +0000926 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
mpagenko9a304ea2020-12-16 15:54:01 +0000927 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +0000928 // meaning transparent setup - no specific VTFD setting required
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000929 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000930 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000931 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000932 // let the FSM proceed ... (from within this state all internal pointers may be expected to be correct)
mpagenkodff5dda2020-08-28 11:52:01 +0000933 pConfigVlanStateAFsm := oFsm.pAdaptFsm
mpagenko9a304ea2020-12-16 15:54:01 +0000934 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +0000935 go func(a_pAFsm *AdapterFsm) {
Himani Chawla4d908332020-08-31 12:30:20 +0530936 _ = a_pAFsm.pFsm.Event(vlanEvRxConfigVtfd)
mpagenkodff5dda2020-08-28 11:52:01 +0000937 }(pConfigVlanStateAFsm)
938 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300939 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
940 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
mpagenko9a304ea2020-12-16 15:54:01 +0000941 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + uint16(oFsm.actualUniVlanConfigRule.TpID)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000942 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300943 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000944 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
945 // setVid is assumed to be masked already by the caller to 12 bit
mpagenko9a304ea2020-12-16 15:54:01 +0000946 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000947 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000948 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000949 vtfdFilterList[0] = oFsm.vlanFilterList[0]
950 oFsm.numVlanFilterEntries = 1
mpagenkodff5dda2020-08-28 11:52:01 +0000951 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300952 EntityID: vtfdID,
mpagenkodff5dda2020-08-28 11:52:01 +0000953 Attributes: me.AttributeValueMap{
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000954 "VlanFilterList": vtfdFilterList, //omci lib wants a slice for serialization
955 "ForwardOperation": uint8(0x10), //VID investigation
956 "NumberOfEntries": oFsm.numVlanFilterEntries,
mpagenkodff5dda2020-08-28 11:52:01 +0000957 },
958 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000959 logger.Debugw(ctx, "UniVlanConfigFsm sendcreate VTFD", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000960 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Girish Gowdra0b235842021-03-09 13:06:46 -0800961 meInstance := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +0000962 oFsm.pAdaptFsm.commChan, meParams)
963 //accept also nil as (error) return value for writing to LastTx
964 // - this avoids misinterpretation of new received OMCI messages
965 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
966 // send shall return (dual format) error code that can be used here for immediate error treatment
967 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +0000968 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +0000969 }
970}
971
dbainbri4d3a0dc2020-12-02 00:33:42 +0000972func (oFsm *UniVlanConfigFsm) enterConfigEvtocd(ctx context.Context, e *fsm.Event) {
973 logger.Debugw(ctx, "UniVlanConfigFsm - start config EVTOCD loop", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000974 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +0000975 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300976 go func() {
mpagenko9a304ea2020-12-16 15:54:01 +0000977 //using the first element in the slice because it's the first flow per definition here
978 errEvto := oFsm.performConfigEvtocdEntries(ctx, 0)
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300979 //This is correct passing scenario
980 if errEvto == nil {
mpagenko9a304ea2020-12-16 15:54:01 +0000981 tpID := oFsm.actualUniVlanConfigRule.TpID
982 vlanID := oFsm.actualUniVlanConfigRule.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +0000983 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
984 logger.Infow(ctx, "Setting multicast MEs, with first flow", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300985 "techProfile": tpID, "gemPort": gemPort, "vlanID": vlanID, "configuredUniFlow": oFsm.configuredUniFlow})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000986 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300987 vlanID)
988 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000989 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300990 log.Fields{"device-id": oFsm.deviceID})
991 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
992 }
993 }
994 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
995 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
996 }
997 }()
mpagenkodff5dda2020-08-28 11:52:01 +0000998}
999
dbainbri4d3a0dc2020-12-02 00:33:42 +00001000func (oFsm *UniVlanConfigFsm) enterVlanConfigDone(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001001
mpagenko9a304ea2020-12-16 15:54:01 +00001002 oFsm.mutexFlowParams.RLock()
1003 defer oFsm.mutexFlowParams.RUnlock()
1004
mpagenkof1fc3862021-02-16 10:09:52 +00001005 logger.Infow(ctx, "UniVlanConfigFsm config done - checking on more flows", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00001006 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1007 "overall-uni-rules": oFsm.numUniFlows, "configured-uni-rules": oFsm.configuredUniFlow})
1008 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1009 if pConfigVlanStateAFsm == nil {
mpagenko551a4d42020-12-08 18:09:20 +00001010 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1011 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1012 //should never happen, else: recovery would be needed from outside the FSM
1013 return
1014 }
1015 pConfigVlanStateBaseFsm := pConfigVlanStateAFsm.pFsm
mpagenko01e726e2020-10-23 09:45:29 +00001016 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1017 //some further flows are to be removed, removal always starts with the first element
mpagenko9a304ea2020-12-16 15:54:01 +00001018 logger.Debugw(ctx, "UniVlanConfigFsm rule removal from ConfigDone", log.Fields{
1019 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
1020 "tp-id": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.TpID,
1021 "set-Vlan": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.SetVid})
1022 // Can't call FSM Event directly, decoupling it
mpagenko01e726e2020-10-23 09:45:29 +00001023 go func(a_pBaseFsm *fsm.FSM) {
1024 _ = a_pBaseFsm.Event(vlanEvRemFlowConfig)
1025 }(pConfigVlanStateBaseFsm)
1026 return
1027 }
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001028 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
1029 oFsm.configuredUniFlow = oFsm.numUniFlows
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001030 if !oFsm.pDeviceHandler.isReconcilingFlows() {
1031 logger.Debugw(ctx, "reconciling - flow processing finished", log.Fields{"device-id": oFsm.deviceID})
1032 oFsm.pDeviceHandler.chReconcilingFlowsFinished <- true
1033 }
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001034 logger.Debugw(ctx, "reconciling - skip enterVlanConfigDone processing",
1035 log.Fields{"numUniFlows": oFsm.numUniFlows, "configuredUniFlow": oFsm.configuredUniFlow, "device-id": oFsm.deviceID})
1036 return
1037 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001038 if oFsm.numUniFlows > oFsm.configuredUniFlow {
mpagenko551a4d42020-12-08 18:09:20 +00001039 if oFsm.configuredUniFlow == 0 {
mpagenko551a4d42020-12-08 18:09:20 +00001040 // this is a restart with a complete new flow, we can re-use the initial flow config control
1041 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenko9a304ea2020-12-16 15:54:01 +00001042 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001043 go func(a_pBaseFsm *fsm.FSM) {
1044 _ = a_pBaseFsm.Event(vlanEvRenew)
1045 }(pConfigVlanStateBaseFsm)
1046 return
1047 }
1048
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001049 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001050 //store the actual rule that shall be worked upon in the following transient states
1051 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +00001052 //tpId of the next rule to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001053 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko551a4d42020-12-08 18:09:20 +00001054 oFsm.TpIDWaitingFor = tpID
mpagenko551a4d42020-12-08 18:09:20 +00001055 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, tpID)
mpagenko9a304ea2020-12-16 15:54:01 +00001056 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request", log.Fields{
1057 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
1058 "set-Vlan": oFsm.actualUniVlanConfigRule.SetVid, "tp-id": tpID, "ProfDone": loTechProfDone})
1059 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001060 go func(aPBaseFsm *fsm.FSM, aTechProfDone bool) {
1061 if aTechProfDone {
1062 // let the vlan processing continue with next rule
1063 _ = aPBaseFsm.Event(vlanEvIncrFlowConfig)
1064 } else {
1065 // set to waiting for Techprofile
1066 _ = aPBaseFsm.Event(vlanEvWaitTPIncr)
1067 }
1068 }(pConfigVlanStateBaseFsm, loTechProfDone)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001069 return
1070 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001071 logger.Debugw(ctx, "UniVlanConfigFsm - VLAN config done: send dh event notification", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001072 "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001073 // it might appear that some flows are requested also after 'flowPushed' event has been generated ...
1074 // state transition notification is checked in deviceHandler
mpagenko551a4d42020-12-08 18:09:20 +00001075 // note: 'flowPushed' event is only generated if all 'pending' rules are configured
mpagenkodff5dda2020-08-28 11:52:01 +00001076 if oFsm.pDeviceHandler != nil {
mpagenkofc4f56e2020-11-04 17:17:49 +00001077 //making use of the add->remove successor enum assumption/definition
dbainbri4d3a0dc2020-12-02 00:33:42 +00001078 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(uint8(oFsm.requestEvent)+oFsm.requestEventOffset))
mpagenkodff5dda2020-08-28 11:52:01 +00001079 }
1080}
1081
dbainbri4d3a0dc2020-12-02 00:33:42 +00001082func (oFsm *UniVlanConfigFsm) enterConfigIncrFlow(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001083
1084 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
1085 logger.Debugw(ctx, "reconciling - skip further processing for incremental flow",
1086 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
1087 go func(a_pBaseFsm *fsm.FSM) {
1088 _ = a_pBaseFsm.Event(vlanEvSkipIncFlowConfig)
1089 }(oFsm.pAdaptFsm.pFsm)
1090 return
1091 }
mpagenko15ff4a52021-03-02 10:09:20 +00001092 oFsm.mutexFlowParams.Lock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001093 logger.Debugw(ctx, "UniVlanConfigFsm - start config further incremental flow", log.Fields{
Girish Gowdra041dcb32020-11-16 16:54:30 -08001094 "in state": e.FSM.Current(), "recent flow-number": oFsm.configuredUniFlow,
mpagenko01e726e2020-10-23 09:45:29 +00001095 "device-id": oFsm.deviceID})
mpagenko551a4d42020-12-08 18:09:20 +00001096 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001097
mpagenko9a304ea2020-12-16 15:54:01 +00001098 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001099 // meaning transparent setup - no specific VTFD setting required
1100 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001101 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001102 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001103 } else {
1104 if oFsm.numVlanFilterEntries == 0 {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001105 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1106 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
mpagenko9a304ea2020-12-16 15:54:01 +00001107 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + uint16(oFsm.actualUniVlanConfigRule.TpID)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001108 //no VTFD yet created
dbainbri4d3a0dc2020-12-02 00:33:42 +00001109 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001110 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001111 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001112 // 'SetVid' below is assumed to be masked already by the caller to 12 bit
mpagenko9a304ea2020-12-16 15:54:01 +00001113 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001114
mpagenko01e726e2020-10-23 09:45:29 +00001115 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001116 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1117 oFsm.numVlanFilterEntries = 1
1118 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001119 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001120 Attributes: me.AttributeValueMap{
1121 "VlanFilterList": vtfdFilterList,
1122 "ForwardOperation": uint8(0x10), //VID investigation
1123 "NumberOfEntries": oFsm.numVlanFilterEntries,
1124 },
1125 }
Girish Gowdra0b235842021-03-09 13:06:46 -08001126 meInstance := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001127 oFsm.pAdaptFsm.commChan, meParams)
1128 //accept also nil as (error) return value for writing to LastTx
1129 // - this avoids misinterpretation of new received OMCI messages
1130 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1131 // send shall return (dual format) error code that can be used here for immediate error treatment
1132 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001133 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001134 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001135 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1136 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
mpagenko551a4d42020-12-08 18:09:20 +00001137 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID +
mpagenko9a304ea2020-12-16 15:54:01 +00001138 uint16(oFsm.actualUniVlanConfigRule.TpID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001139
dbainbri4d3a0dc2020-12-02 00:33:42 +00001140 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001141 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001142 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001143 // setVid is assumed to be masked already by the caller to 12 bit
1144 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] =
mpagenko9a304ea2020-12-16 15:54:01 +00001145 uint16(oFsm.actualUniVlanConfigRule.SetVid)
mpagenko01e726e2020-10-23 09:45:29 +00001146 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001147
1148 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
1149 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
1150 // new vlan associated with a different TP.
mpagenko9a304ea2020-12-16 15:54:01 +00001151 vtfdFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001152
1153 oFsm.numVlanFilterEntries++
1154 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001155 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001156 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001157 "VlanFilterList": vtfdFilterList,
1158 "ForwardOperation": uint8(0x10), //VID investigation
1159 "NumberOfEntries": oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001160 },
1161 }
Girish Gowdra0b235842021-03-09 13:06:46 -08001162 meInstance := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001163 oFsm.pAdaptFsm.commChan, meParams)
1164 //accept also nil as (error) return value for writing to LastTx
1165 // - this avoids misinterpretation of new received OMCI messages
1166 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1167 // send shall return (dual format) error code that can be used here for immediate error treatment
1168 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001169 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001170 }
mpagenko15ff4a52021-03-02 10:09:20 +00001171 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001172 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001173 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001174 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001175 logger.Errorw(ctx, "VTFD create/set failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001176 log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001177 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001178 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001179 go func(a_pBaseFsm *fsm.FSM) {
1180 _ = a_pBaseFsm.Event(vlanEvReset)
1181 }(pConfigVlanStateBaseFsm)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001182 return
1183 }
1184 }
mpagenko15ff4a52021-03-02 10:09:20 +00001185 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001186 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
mpagenko15ff4a52021-03-02 10:09:20 +00001187 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001188 go func() {
mpagenko15ff4a52021-03-02 10:09:20 +00001189 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001190 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko15ff4a52021-03-02 10:09:20 +00001191 configuredUniFlow := oFsm.configuredUniFlow
1192 oFsm.mutexFlowParams.RUnlock()
1193 errEvto := oFsm.performConfigEvtocdEntries(ctx, configuredUniFlow)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001194 //This is correct passing scenario
1195 if errEvto == nil {
1196 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
dbainbri4d3a0dc2020-12-02 00:33:42 +00001197 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
mpagenko15ff4a52021-03-02 10:09:20 +00001198 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001199 vlanID := oFsm.actualUniVlanConfigRule.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +00001200 logger.Infow(ctx, "Setting multicast MEs for additional flows", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001201 "techProfile": tpID, "gemPort": gemPort,
1202 "vlanID": vlanID, "configuredUniFlow": oFsm.configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +00001203 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001204 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001205 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001206 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001207 log.Fields{"device-id": oFsm.deviceID})
1208 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1209 }
1210 }
1211 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
1212 }
1213 }()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001214}
1215
dbainbri4d3a0dc2020-12-02 00:33:42 +00001216func (oFsm *UniVlanConfigFsm) enterRemoveFlow(ctx context.Context, e *fsm.Event) {
mpagenko551a4d42020-12-08 18:09:20 +00001217 oFsm.mutexFlowParams.RLock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001218 logger.Debugw(ctx, "UniVlanConfigFsm - start removing the top remove-flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001219 "in state": e.FSM.Current(), "with last cookie": oFsm.uniRemoveFlowsSlice[0].cookie,
1220 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001221
mpagenkofc4f56e2020-11-04 17:17:49 +00001222 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
1223 loAllowSpecificOmciConfig := oFsm.pDeviceHandler.ReadyForSpecificOmciConfig
mpagenko01e726e2020-10-23 09:45:29 +00001224 loVlanEntryClear := uint8(0)
1225 loVlanEntryRmPos := uint8(0x80) //with indication 'invalid' in bit 7
1226 //shallow copy is sufficient as no reference variables are used within struct
1227 loRuleParams := oFsm.uniRemoveFlowsSlice[0].vlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +00001228 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001229 logger.Debugw(ctx, "UniVlanConfigFsm - remove-flow parameters are", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001230 "match vid": loRuleParams.MatchVid, "match Pcp": loRuleParams.MatchPcp,
1231 "set vid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
1232 "device-id": oFsm.deviceID})
1233
1234 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
1235 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001236 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD removal required for transparent flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001237 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1238 } else {
1239 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization and 're-copy'
1240 if oFsm.numVlanFilterEntries == 1 {
mpagenko551a4d42020-12-08 18:09:20 +00001241 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + uint16(loRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00001242 //only one active VLAN entry (hopefully the SetVID we want to remove - should be, but not verified ..)
1243 // so we can just delete the VTFD entry
dbainbri4d3a0dc2020-12-02 00:33:42 +00001244 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD delete (no more vlan filters)",
mpagenko01e726e2020-10-23 09:45:29 +00001245 log.Fields{"current vlan list": oFsm.vlanFilterList,
1246 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001247 loVlanEntryClear = 1 //full VlanFilter clear request
1248 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
Girish Gowdra0b235842021-03-09 13:06:46 -08001249 meInstance := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001250 oFsm.pAdaptFsm.commChan, vtfdID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001251 oFsm.pLastTxMeInstance = meInstance
1252 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001253 logger.Debugw(ctx, "UniVlanConfigFsm delete VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001254 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.getDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +00001255 }
mpagenko01e726e2020-10-23 09:45:29 +00001256 } else {
1257 //many VTFD already should exists - find and remove the one concerned by the actual remove rule
1258 // by updating the VTFD per set command with new valid list
dbainbri4d3a0dc2020-12-02 00:33:42 +00001259 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD removal of requested VLAN from the list on OMCI",
mpagenko01e726e2020-10-23 09:45:29 +00001260 log.Fields{"current vlan list": oFsm.vlanFilterList,
1261 "set-vlan": loRuleParams.SetVid, "device-id": oFsm.deviceID})
1262 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1263 if loRuleParams.SetVid == uint32(oFsm.vlanFilterList[i]) {
1264 loVlanEntryRmPos = i
1265 break //abort search
1266 }
1267 }
1268 if loVlanEntryRmPos < cVtfdTableSize {
mpagenko551a4d42020-12-08 18:09:20 +00001269 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + uint16(loRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00001270 //valid entry was found - to be eclipsed
1271 loVlanEntryClear = 2 //VlanFilter remove request for a specific entry
1272 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1273 if i < loVlanEntryRmPos {
1274 vtfdFilterList[i] = oFsm.vlanFilterList[i] //copy original
1275 } else if i < (cVtfdTableSize - 1) {
1276 vtfdFilterList[i] = oFsm.vlanFilterList[i+1] //copy successor (including 0 elements)
1277 } else {
1278 vtfdFilterList[i] = 0 //set last byte if needed
1279 }
1280 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001281 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001282 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001283 "new vlan list": vtfdFilterList, "device-id": oFsm.deviceID})
1284
mpagenkofc4f56e2020-11-04 17:17:49 +00001285 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001286 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
Girish Gowdra0b235842021-03-09 13:06:46 -08001287 meInstance := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001288 oFsm.pAdaptFsm.commChan, vtfdID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001289 oFsm.pLastTxMeInstance = meInstance
1290 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001291 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001292 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.getDeviceReasonString()})
mpagenko01e726e2020-10-23 09:45:29 +00001293 }
mpagenko01e726e2020-10-23 09:45:29 +00001294 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001295 logger.Warnw(ctx, "UniVlanConfigFsm: requested VLAN for removal not found in list - ignore and continue (no VTFD set)",
mpagenko01e726e2020-10-23 09:45:29 +00001296 log.Fields{"device-id": oFsm.deviceID})
1297 }
1298 }
1299 if loVlanEntryClear > 0 {
mpagenkofc4f56e2020-11-04 17:17:49 +00001300 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
1301 //waiting on response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001302 err := oFsm.waitforOmciResponse(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001303 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001304 logger.Errorw(ctx, "VTFD delete/reset failed, aborting VlanConfig FSM!",
mpagenkofc4f56e2020-11-04 17:17:49 +00001305 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001306 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001307 go func(a_pBaseFsm *fsm.FSM) {
1308 _ = a_pBaseFsm.Event(vlanEvReset)
1309 }(pConfigVlanStateBaseFsm)
1310 return
1311 }
mpagenko01e726e2020-10-23 09:45:29 +00001312 }
1313
mpagenko15ff4a52021-03-02 10:09:20 +00001314 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00001315 if loVlanEntryClear == 1 {
1316 oFsm.vlanFilterList[0] = 0 //first entry is the only that can contain the previous only-one element
1317 oFsm.numVlanFilterEntries = 0
1318 } else if loVlanEntryClear == 2 {
1319 // new VlanFilterList should be one entry smaller now - copy from last configured entry
1320 // this loop now includes the 0 element on previous last valid entry
1321 for i := uint8(0); i <= oFsm.numVlanFilterEntries; i++ {
1322 oFsm.vlanFilterList[i] = vtfdFilterList[i]
1323 }
1324 oFsm.numVlanFilterEntries--
1325 }
mpagenko15ff4a52021-03-02 10:09:20 +00001326 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001327 }
1328 }
1329
mpagenkofc4f56e2020-11-04 17:17:49 +00001330 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001331 go oFsm.removeEvtocdEntries(ctx, loRuleParams)
mpagenkofc4f56e2020-11-04 17:17:49 +00001332 } else {
1333 // OMCI processing is not done, expectation is to have the ONU in some basic config state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001334 logger.Debugw(ctx, "UniVlanConfigFsm remove EVTOCD OMCI handling skipped based on device state", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +00001335 "device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001336 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001337 go func(a_pBaseFsm *fsm.FSM) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001338 _ = a_pBaseFsm.Event(vlanEvRemFlowDone, loRuleParams.TpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001339 }(pConfigVlanStateBaseFsm)
1340 }
mpagenkodff5dda2020-08-28 11:52:01 +00001341}
1342
dbainbri4d3a0dc2020-12-02 00:33:42 +00001343func (oFsm *UniVlanConfigFsm) enterVlanCleanupDone(ctx context.Context, e *fsm.Event) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001344 var tpID uint8
1345 // Extract the tpID
1346 if len(e.Args) > 0 {
1347 tpID = e.Args[0].(uint8)
1348 logger.Debugw(ctx, "UniVlanConfigFsm - flow removed for tp id", log.Fields{"device-id": oFsm.deviceID, "tpID": e.Args[0].(uint8)})
1349 } else {
1350 logger.Warnw(ctx, "UniVlanConfigFsm - tp id not available", log.Fields{"device-id": oFsm.deviceID})
1351 }
mpagenko01e726e2020-10-23 09:45:29 +00001352 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001353 deletedCookie := oFsm.uniRemoveFlowsSlice[0].cookie
1354 logger.Debugw(ctx, "UniVlanConfigFsm - removing the removal data", log.Fields{
1355 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1356 "removed cookie": deletedCookie, "waitForDeleteCookie": oFsm.delayNewRuleCookie})
1357
mpagenko01e726e2020-10-23 09:45:29 +00001358 if len(oFsm.uniRemoveFlowsSlice) <= 1 {
1359 oFsm.uniRemoveFlowsSlice = nil //reset the slice
dbainbri4d3a0dc2020-12-02 00:33:42 +00001360 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - last remove-flow deleted", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001361 "device-id": oFsm.deviceID})
1362 } else {
1363 //cut off the actual flow by slicing out the first element
1364 oFsm.uniRemoveFlowsSlice = append(
1365 oFsm.uniRemoveFlowsSlice[:0],
1366 oFsm.uniRemoveFlowsSlice[1:]...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001367 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow deleted from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001368 "device-id": oFsm.deviceID})
1369 }
1370 oFsm.mutexFlowParams.Unlock()
1371
mpagenkof1fc3862021-02-16 10:09:52 +00001372 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
mpagenko01e726e2020-10-23 09:45:29 +00001373 //return to the basic config verification state
mpagenkodff5dda2020-08-28 11:52:01 +00001374 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1375 if pConfigVlanStateAFsm != nil {
mpagenko9a304ea2020-12-16 15:54:01 +00001376 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +00001377 go func(a_pAFsm *AdapterFsm) {
1378 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001379 _ = a_pAFsm.pFsm.Event(vlanEvFlowDataRemoved)
mpagenkodff5dda2020-08-28 11:52:01 +00001380 }
1381 }(pConfigVlanStateAFsm)
1382 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001383
mpagenkobb47bc22021-04-20 13:29:09 +00001384 oFsm.mutexFlowParams.Lock()
Girish Gowdra26a40922021-01-29 17:14:34 -08001385 noOfFlowRem := len(oFsm.uniRemoveFlowsSlice)
mpagenkof1fc3862021-02-16 10:09:52 +00001386 if deletedCookie == oFsm.delayNewRuleCookie {
1387 // flush the channel CookieDeleted to ensure it is not lingering from some previous (aborted) activity
1388 select {
1389 case <-oFsm.chCookieDeleted:
1390 logger.Debug(ctx, "flushed CookieDeleted")
1391 default:
1392 }
1393 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue
1394 }
mpagenkobb47bc22021-04-20 13:29:09 +00001395 // If all pending flow-removes are completed and TP ID is valid go on processing any pending TP delete
1396 if oFsm.signalOnFlowDelete && noOfFlowRem == 0 && tpID > 0 {
1397 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 -08001398 // If we are here then all flows are removed.
mpagenkobb47bc22021-04-20 13:29:09 +00001399 if len(oFsm.flowDeleteChannel) == 0 { //channel not yet in use
1400 oFsm.flowDeleteChannel <- true
1401 oFsm.signalOnFlowDelete = false
1402 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001403 }
mpagenkobb47bc22021-04-20 13:29:09 +00001404 oFsm.mutexFlowParams.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001405}
1406
dbainbri4d3a0dc2020-12-02 00:33:42 +00001407func (oFsm *UniVlanConfigFsm) enterResetting(ctx context.Context, e *fsm.Event) {
1408 logger.Debugw(ctx, "UniVlanConfigFsm resetting", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001409
1410 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1411 if pConfigVlanStateAFsm != nil {
1412 // abort running message processing
1413 fsmAbortMsg := Message{
1414 Type: TestMsg,
1415 Data: TestMessage{
1416 TestMessageVal: AbortMessageProcessing,
1417 },
1418 }
1419 pConfigVlanStateAFsm.commChan <- fsmAbortMsg
1420
mpagenko9a304ea2020-12-16 15:54:01 +00001421 //try to restart the FSM to 'disabled'
1422 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +00001423 go func(a_pAFsm *AdapterFsm) {
1424 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301425 _ = a_pAFsm.pFsm.Event(vlanEvRestart)
mpagenkodff5dda2020-08-28 11:52:01 +00001426 }
1427 }(pConfigVlanStateAFsm)
1428 }
1429}
1430
dbainbri4d3a0dc2020-12-02 00:33:42 +00001431func (oFsm *UniVlanConfigFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
1432 logger.Debugw(ctx, "UniVlanConfigFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001433 oFsm.pLastTxMeInstance = nil
mpagenkodff5dda2020-08-28 11:52:01 +00001434 if oFsm.pDeviceHandler != nil {
mpagenko2418ab02020-11-12 12:58:06 +00001435 //TODO: to clarify with improved error treatment for VlanConfigFsm (timeout,reception) errors
1436 // current code removes the complete FSM including all flow/rule configuration done so far
1437 // this might be a bit to much, it would require fully new flow config from rwCore (at least on OnuDown/up)
1438 // maybe a more sophisticated approach is possible without clearing the data
mpagenko9a304ea2020-12-16 15:54:01 +00001439 oFsm.mutexFlowParams.RLock()
mpagenko2418ab02020-11-12 12:58:06 +00001440 if oFsm.clearPersistency {
1441 //permanently remove possibly stored persistent data
1442 if len(oFsm.uniVlanFlowParamsSlice) > 0 {
1443 var emptySlice = make([]uniVlanFlowParams, 0)
mpagenkof1fc3862021-02-16 10:09:52 +00001444 _ = oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID, &emptySlice, true) //ignore errors
mpagenko2418ab02020-11-12 12:58:06 +00001445 }
1446 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001447 logger.Debugw(ctx, "UniVlanConfigFsm persistency data not cleared", log.Fields{"device-id": oFsm.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001448 }
mpagenkof1fc3862021-02-16 10:09:52 +00001449 if oFsm.delayNewRuleCookie != 0 {
1450 // looks like the waiting AddFlow is stuck
1451 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue/treminate
1452 }
mpagenko9a304ea2020-12-16 15:54:01 +00001453 oFsm.mutexFlowParams.RUnlock()
mpagenko2418ab02020-11-12 12:58:06 +00001454 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001455 go oFsm.pDeviceHandler.RemoveVlanFilterFsm(ctx, oFsm.pOnuUniPort)
mpagenkodff5dda2020-08-28 11:52:01 +00001456 }
1457}
1458
dbainbri4d3a0dc2020-12-02 00:33:42 +00001459func (oFsm *UniVlanConfigFsm) processOmciVlanMessages(ctx context.Context) { //ctx context.Context?
1460 logger.Debugw(ctx, "Start UniVlanConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001461loop:
1462 for {
mpagenkodff5dda2020-08-28 11:52:01 +00001463 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00001464 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001465 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +05301466 message, ok := <-oFsm.pAdaptFsm.commChan
1467 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001468 logger.Info(ctx, "UniVlanConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301469 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
1470 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1471 break loop
1472 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001473 logger.Debugw(ctx, "UniVlanConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301474
1475 switch message.Type {
1476 case TestMsg:
1477 msg, _ := message.Data.(TestMessage)
1478 if msg.TestMessageVal == AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001479 logger.Infow(ctx, "UniVlanConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001480 break loop
1481 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001482 logger.Warnw(ctx, "UniVlanConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Himani Chawla4d908332020-08-31 12:30:20 +05301483 case OMCI:
1484 msg, _ := message.Data.(OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001485 oFsm.handleOmciVlanConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301486 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001487 logger.Warn(ctx, "UniVlanConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301488 "message.Type": message.Type})
mpagenkodff5dda2020-08-28 11:52:01 +00001489 }
1490 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001491 logger.Infow(ctx, "End UniVlanConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001492}
1493
dbainbri4d3a0dc2020-12-02 00:33:42 +00001494func (oFsm *UniVlanConfigFsm) handleOmciVlanConfigMessage(ctx context.Context, msg OmciMessage) {
1495 logger.Debugw(ctx, "Rx OMCI UniVlanConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001496 "msgType": msg.OmciMsg.MessageType})
1497
1498 switch msg.OmciMsg.MessageType {
1499 case omci.CreateResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001500 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001501 if err := oFsm.handleOmciCreateResponseMessage(ctx, msg.OmciPacket); err != nil {
1502 logger.Warnw(ctx, "CreateResponse handling aborted", log.Fields{"err": err})
mpagenkodff5dda2020-08-28 11:52:01 +00001503 return
1504 }
mpagenkodff5dda2020-08-28 11:52:01 +00001505 } //CreateResponseType
1506 case omci.SetResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001507 { //leave that here as direct code as most often used
mpagenkodff5dda2020-08-28 11:52:01 +00001508 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1509 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001510 logger.Errorw(ctx, "Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001511 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001512 return
1513 }
1514 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1515 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001516 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001517 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001518 return
1519 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001520 logger.Debugw(ctx, "UniVlanConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkodff5dda2020-08-28 11:52:01 +00001521 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001522 logger.Errorw(ctx, "UniVlanConfigFsm Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001523 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
mpagenkodff5dda2020-08-28 11:52:01 +00001524 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1525 return
1526 }
mpagenko01e726e2020-10-23 09:45:29 +00001527 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1528 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1529 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001530 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "MulticastOperationsProfile":
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001531 { // let the MultiEntity config proceed by stopping the wait function
mpagenkodff5dda2020-08-28 11:52:01 +00001532 oFsm.omciMIdsResponseReceived <- true
1533 }
1534 }
1535 }
1536 } //SetResponseType
mpagenko01e726e2020-10-23 09:45:29 +00001537 case omci.DeleteResponseType:
1538 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001539 if err := oFsm.handleOmciDeleteResponseMessage(ctx, msg.OmciPacket); err != nil {
1540 logger.Warnw(ctx, "DeleteResponse handling aborted", log.Fields{"err": err})
mpagenko01e726e2020-10-23 09:45:29 +00001541 return
1542 }
1543 } //DeleteResponseType
mpagenkodff5dda2020-08-28 11:52:01 +00001544 default:
1545 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001546 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00001547 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001548 return
1549 }
1550 }
1551}
1552
dbainbri4d3a0dc2020-12-02 00:33:42 +00001553func (oFsm *UniVlanConfigFsm) handleOmciCreateResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00001554 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeCreateResponse)
1555 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001556 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001557 log.Fields{"device-id": oFsm.deviceID})
1558 return fmt.Errorf("omci msg layer could not be detected for CreateResponse for device-id %x",
1559 oFsm.deviceID)
1560 }
1561 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
1562 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001563 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001564 log.Fields{"device-id": oFsm.deviceID})
1565 return fmt.Errorf("omci msg layer could not be assigned for CreateResponse for device-id %x",
1566 oFsm.deviceID)
1567 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001568 logger.Debugw(ctx, "UniVlanConfigFsm CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001569 if msgObj.Result != me.Success && msgObj.Result != me.InstanceExists {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001570 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"device-id": oFsm.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00001571 "Error": msgObj.Result})
1572 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1573 return fmt.Errorf("omci CreateResponse Error for device-id %x",
1574 oFsm.deviceID)
1575 }
1576 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1577 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1578 // to satisfy StaticCodeAnalysis I had to move the small processing into a separate method :-(
1579 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001580 case "VlanTaggingFilterData", "MulticastOperationsProfile",
1581 "MulticastSubscriberConfigInfo", "MacBridgePortConfigurationData",
1582 "ExtendedVlanTaggingOperationConfigurationData":
mpagenko01e726e2020-10-23 09:45:29 +00001583 {
1584 if oFsm.pAdaptFsm.pFsm.Current() == vlanStConfigVtfd {
1585 // Only if CreateResponse is received from first flow entry - let the FSM proceed ...
1586 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigVtfd)
1587 } else { // let the MultiEntity config proceed by stopping the wait function
1588 oFsm.omciMIdsResponseReceived <- true
1589 }
1590 }
1591 }
1592 }
1593 return nil
1594}
1595
dbainbri4d3a0dc2020-12-02 00:33:42 +00001596func (oFsm *UniVlanConfigFsm) handleOmciDeleteResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00001597 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeDeleteResponse)
1598 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001599 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001600 log.Fields{"device-id": oFsm.deviceID})
1601 return fmt.Errorf("omci msg layer could not be detected for DeleteResponse for device-id %x",
1602 oFsm.deviceID)
1603 }
1604 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
1605 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001606 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001607 log.Fields{"device-id": oFsm.deviceID})
1608 return fmt.Errorf("omci msg layer could not be assigned for DeleteResponse for device-id %x",
1609 oFsm.deviceID)
1610 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001611 logger.Debugw(ctx, "UniVlanConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko01e726e2020-10-23 09:45:29 +00001612 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001613 logger.Errorw(ctx, "UniVlanConfigFsm - Omci DeleteResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001614 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1615 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1616 return fmt.Errorf("omci DeleteResponse Error for device-id %x",
1617 oFsm.deviceID)
1618 }
1619 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1620 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1621 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001622 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData":
mpagenko01e726e2020-10-23 09:45:29 +00001623 { // let the MultiEntity config proceed by stopping the wait function
1624 oFsm.omciMIdsResponseReceived <- true
1625 }
1626 }
1627 }
1628 return nil
1629}
1630
dbainbri4d3a0dc2020-12-02 00:33:42 +00001631func (oFsm *UniVlanConfigFsm) performConfigEvtocdEntries(ctx context.Context, aFlowEntryNo uint8) error {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001632 if aFlowEntryNo == 0 {
1633 // EthType set only at first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00001634 // EVTOCD ME is expected to exist at this point already from MIB-Download (with AssociationType/Pointer)
1635 // we need to extend the configuration by EthType definition and, to be sure, downstream 'inverse' mode
dbainbri4d3a0dc2020-12-02 00:33:42 +00001636 logger.Debugw(ctx, "UniVlanConfigFsm Tx Create::EVTOCD", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00001637 "EntitytId": strconv.FormatInt(int64(oFsm.evtocdID), 16),
1638 "i/oEthType": strconv.FormatInt(int64(cDefaultTpid), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001639 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001640 associationType := 2 // default to uniPPTP
1641 if oFsm.pOnuUniPort.portType == uniVEIP {
1642 associationType = 10
1643 }
1644 // Create the EVTOCD ME
mpagenkodff5dda2020-08-28 11:52:01 +00001645 meParams := me.ParamData{
1646 EntityID: oFsm.evtocdID,
1647 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001648 "AssociationType": uint8(associationType),
1649 "AssociatedMePointer": oFsm.pOnuUniPort.entityID,
mpagenkodff5dda2020-08-28 11:52:01 +00001650 },
1651 }
Girish Gowdra0b235842021-03-09 13:06:46 -08001652 meInstance := oFsm.pOmciCC.sendCreateEvtocdVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001653 oFsm.pAdaptFsm.commChan, meParams)
1654 //accept also nil as (error) return value for writing to LastTx
1655 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001656 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001657
1658 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001659 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001660 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001661 logger.Errorw(ctx, "Evtocd create failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001662 log.Fields{"device-id": oFsm.deviceID})
1663 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1664 return fmt.Errorf("evtocd create failed %s, error %s", oFsm.deviceID, err)
1665 }
1666
1667 // Set the EVTOCD ME default params
1668 meParams = me.ParamData{
1669 EntityID: oFsm.evtocdID,
1670 Attributes: me.AttributeValueMap{
1671 "InputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
1672 "OutputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
1673 "DownstreamMode": uint8(cDefaultDownstreamMode),
1674 },
1675 }
Girish Gowdra0b235842021-03-09 13:06:46 -08001676 meInstance = oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001677 oFsm.pAdaptFsm.commChan, meParams)
1678 //accept also nil as (error) return value for writing to LastTx
1679 // - this avoids misinterpretation of new received OMCI messages
1680 oFsm.pLastTxMeInstance = meInstance
1681
1682 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001683 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001684 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001685 logger.Errorw(ctx, "Evtocd set TPID failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001686 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301687 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001688 return fmt.Errorf("evtocd set TPID failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00001689 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001690 } //first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00001691
mpagenko551a4d42020-12-08 18:09:20 +00001692 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001693 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00001694 //transparent transmission required
mpagenko551a4d42020-12-08 18:09:20 +00001695 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001696 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged transparent rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001697 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001698 sliceEvtocdRule := make([]uint8, 16)
1699 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1700 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1701 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1702 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1703 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1704
1705 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1706 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
1707 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1708 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1709 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1710
1711 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1712 0<<cTreatTTROffset| // Do not pop any tags
1713 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1714 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1715 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1716
1717 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1718 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
1719 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1720 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
1721
1722 meParams := me.ParamData{
1723 EntityID: oFsm.evtocdID,
1724 Attributes: me.AttributeValueMap{
1725 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1726 },
1727 }
Girish Gowdra0b235842021-03-09 13:06:46 -08001728 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001729 oFsm.pAdaptFsm.commChan, meParams)
1730 //accept also nil as (error) return value for writing to LastTx
1731 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001732 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001733
1734 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001735 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001736 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001737 logger.Errorw(ctx, "Evtocd set transparent singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001738 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301739 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001740 return fmt.Errorf("evtocd set transparent singletagged rule failed %s, error %s", oFsm.deviceID, err)
1741
mpagenkodff5dda2020-08-28 11:52:01 +00001742 }
1743 } else {
1744 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
1745 if oFsm.acceptIncrementalEvtoOption {
mpagenko9a304ea2020-12-16 15:54:01 +00001746 matchPcp := oFsm.actualUniVlanConfigRule.MatchPcp
1747 matchVid := oFsm.actualUniVlanConfigRule.MatchVid
1748 setPcp := oFsm.actualUniVlanConfigRule.SetPcp
1749 setVid := oFsm.actualUniVlanConfigRule.SetVid
mpagenkodff5dda2020-08-28 11:52:01 +00001750 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001751 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged translation rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001752 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001753 sliceEvtocdRule := make([]uint8, 16)
1754 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1755 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1756 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1757 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1758 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1759
1760 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00001761 oFsm.actualUniVlanConfigRule.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
1762 oFsm.actualUniVlanConfigRule.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
mpagenkodff5dda2020-08-28 11:52:01 +00001763 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1764 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1765
1766 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00001767 oFsm.actualUniVlanConfigRule.TagsToRemove<<cTreatTTROffset| // either 1 or 0
mpagenkodff5dda2020-08-28 11:52:01 +00001768 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1769 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1770 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1771
1772 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00001773 oFsm.actualUniVlanConfigRule.SetPcp<<cTreatPrioOffset| // as configured in flow
1774 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| //as configured in flow
mpagenkodff5dda2020-08-28 11:52:01 +00001775 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00001776 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001777
1778 meParams := me.ParamData{
1779 EntityID: oFsm.evtocdID,
1780 Attributes: me.AttributeValueMap{
1781 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1782 },
1783 }
Girish Gowdra0b235842021-03-09 13:06:46 -08001784 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001785 oFsm.pAdaptFsm.commChan, meParams)
1786 //accept also nil as (error) return value for writing to LastTx
1787 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001788 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001789
1790 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001791 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001792 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001793 logger.Errorw(ctx, "Evtocd set singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001794 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301795 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001796 return fmt.Errorf("evtocd set singletagged translation rule failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00001797 }
1798 } else {
1799 //not transparent and not acceptIncrementalEvtoOption untagged/priotagged->singletagged
1800 { // just for local var's
1801 // this defines stacking scenario: untagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00001802 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD untagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001803 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001804 sliceEvtocdRule := make([]uint8, 16)
1805 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1806 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1807 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1808 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1809 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1810
1811 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1812 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
1813 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1814 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1815 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1816
1817 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1818 0<<cTreatTTROffset| // Do not pop any tags
1819 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1820 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1821 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1822
1823 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1824 0<<cTreatPrioOffset| // vlan prio set to 0
1825 // (as done in Py code, maybe better option would be setPcp here, which still could be 0?)
mpagenko9a304ea2020-12-16 15:54:01 +00001826 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| // Outer VID don't care
mpagenkodff5dda2020-08-28 11:52:01 +00001827 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
1828
mpagenko551a4d42020-12-08 18:09:20 +00001829 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001830 meParams := me.ParamData{
1831 EntityID: oFsm.evtocdID,
1832 Attributes: me.AttributeValueMap{
1833 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1834 },
1835 }
Girish Gowdra0b235842021-03-09 13:06:46 -08001836 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001837 oFsm.pAdaptFsm.commChan, meParams)
1838 //accept also nil as (error) return value for writing to LastTx
1839 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001840 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001841
1842 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001843 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001844 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001845 logger.Errorw(ctx, "Evtocd set untagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001846 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301847 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001848 return fmt.Errorf("evtocd set untagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
1849
mpagenkodff5dda2020-08-28 11:52:01 +00001850 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001851 } // just for local var's
mpagenkodff5dda2020-08-28 11:52:01 +00001852 { // just for local var's
1853 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00001854 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD priotagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001855 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001856 sliceEvtocdRule := make([]uint8, 16)
1857 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1858 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1859 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1860 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1861 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1862
1863 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1864 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
1865 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
1866 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1867 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1868
1869 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1870 1<<cTreatTTROffset| // pop the prio-tag
1871 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1872 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1873 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1874
mpagenko551a4d42020-12-08 18:09:20 +00001875 oFsm.mutexFlowParams.RLock()
mpagenkodff5dda2020-08-28 11:52:01 +00001876 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1877 cCopyPrioFromInner<<cTreatPrioOffset| // vlan copy from PrioTag
1878 // (as done in Py code, maybe better option would be setPcp here, which still could be PrioCopy?)
mpagenko9a304ea2020-12-16 15:54:01 +00001879 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| // Outer VID as configured
mpagenkodff5dda2020-08-28 11:52:01 +00001880 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00001881 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001882
1883 meParams := me.ParamData{
1884 EntityID: oFsm.evtocdID,
1885 Attributes: me.AttributeValueMap{
1886 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1887 },
1888 }
Girish Gowdra0b235842021-03-09 13:06:46 -08001889 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001890 oFsm.pAdaptFsm.commChan, meParams)
1891 //accept also nil as (error) return value for writing to LastTx
1892 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001893 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001894
1895 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001896 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001897 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001898 logger.Errorw(ctx, "Evtocd set priotagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001899 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301900 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001901 return fmt.Errorf("evtocd set priotagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
1902
mpagenkodff5dda2020-08-28 11:52:01 +00001903 }
1904 } //just for local var's
1905 }
1906 }
1907
mpagenkofc4f56e2020-11-04 17:17:49 +00001908 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001909 logger.Debugw(ctx, "EVTOCD set loop finished", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001910 oFsm.configuredUniFlow++ // one (more) flow configured
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001911 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00001912}
1913
dbainbri4d3a0dc2020-12-02 00:33:42 +00001914func (oFsm *UniVlanConfigFsm) removeEvtocdEntries(ctx context.Context, aRuleParams uniVlanRuleParams) {
mpagenko01e726e2020-10-23 09:45:29 +00001915 // configured Input/Output TPID is not modified again - no influence if no filter is applied
1916 if aRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
1917 //transparent transmission was set
1918 //perhaps the config is not needed for removal,
1919 // but the specific InnerTpid setting is removed in favor of the real default forwarding rule
dbainbri4d3a0dc2020-12-02 00:33:42 +00001920 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset to default single tagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001921 "device-id": oFsm.deviceID})
1922 sliceEvtocdRule := make([]uint8, 16)
1923 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1924 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1925 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1926 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1927 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1928
1929 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1930 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
1931 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1932 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1933 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1934
1935 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1936 0<<cTreatTTROffset| // Do not pop any tags
1937 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1938 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1939 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1940
1941 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1942 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
1943 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1944 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
1945
1946 meParams := me.ParamData{
1947 EntityID: oFsm.evtocdID,
1948 Attributes: me.AttributeValueMap{
1949 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1950 },
1951 }
Girish Gowdra0b235842021-03-09 13:06:46 -08001952 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00001953 oFsm.pAdaptFsm.commChan, meParams)
1954 //accept also nil as (error) return value for writing to LastTx
1955 // - this avoids misinterpretation of new received OMCI messages
1956 oFsm.pLastTxMeInstance = meInstance
1957
1958 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001959 err := oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001960 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001961 logger.Errorw(ctx, "Evtocd reset singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001962 log.Fields{"device-id": oFsm.deviceID})
1963 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1964 return
1965 }
1966 } else {
1967 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
1968 if oFsm.acceptIncrementalEvtoOption {
1969 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001970 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear single tagged translation rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001971 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
1972 sliceEvtocdRule := make([]uint8, 16)
1973 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1974 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1975 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1976 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1977 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1978
1979 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1980 aRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
1981 aRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
1982 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1983 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1984
1985 // delete indication for the indicated Filter
1986 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
1987 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
1988
1989 meParams := me.ParamData{
1990 EntityID: oFsm.evtocdID,
1991 Attributes: me.AttributeValueMap{
1992 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1993 },
1994 }
Girish Gowdra0b235842021-03-09 13:06:46 -08001995 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00001996 oFsm.pAdaptFsm.commChan, meParams)
1997 //accept also nil as (error) return value for writing to LastTx
1998 // - this avoids misinterpretation of new received OMCI messages
1999 oFsm.pLastTxMeInstance = meInstance
2000
2001 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002002 err := oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002003 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002004 logger.Errorw(ctx, "Evtocd clear singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002005 log.Fields{"device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
2006 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2007 return
2008 }
2009 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002010 // VOL-3685
2011 // NOTE: With ALPHA ONUs it was seen that just resetting a particular entry in the EVTOCD table
2012 // and re-configuring a new entry would not work. The old entry is removed and new entry is created
2013 // indeed, but the traffic landing upstream would carry old vlan sometimes.
2014 // This is only a WORKAROUND which basically deletes the entire EVTOCD ME and re-creates it again
2015 // later when the flow is being re-installed.
2016 // Of course this is applicable to case only where single service (or single tcont) is in use and
2017 // there is only one service vlan (oFsm.acceptIncrementalEvtoOption is false in this case).
2018 // Interstingly this problem has not been observed in multi-tcont (or multi-service) scenario (in
2019 // which case the oFsm.acceptIncrementalEvtoOption is set to true).
2020 if oFsm.configuredUniFlow == 0 && !oFsm.acceptIncrementalEvtoOption {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002021 logger.Debugw(ctx, "UniVlanConfigFsm Tx Remove::EVTOCD", log.Fields{"device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002022 // When there are no more EVTOCD vlan configurations on the ONU and acceptIncrementalEvtoOption
2023 // is not enabled, delete the EVTOCD ME.
mpagenko01e726e2020-10-23 09:45:29 +00002024 meParams := me.ParamData{
2025 EntityID: oFsm.evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002026 }
Girish Gowdra0b235842021-03-09 13:06:46 -08002027 meInstance := oFsm.pOmciCC.sendDeleteEvtocd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00002028 oFsm.pAdaptFsm.commChan, meParams)
2029 //accept also nil as (error) return value for writing to LastTx
2030 // - this avoids misinterpretation of new received OMCI messages
2031 oFsm.pLastTxMeInstance = meInstance
2032
2033 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002034 err := oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002035 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002036 logger.Errorw(ctx, "Evtocd delete rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002037 log.Fields{"device-id": oFsm.deviceID})
2038 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2039 return
2040 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002041 } else {
2042 // NOTE : We should ideally never ether this section when oFsm.acceptIncrementalEvtoOption is set to false
2043 // This is true for only ATT/DT workflow
dbainbri4d3a0dc2020-12-02 00:33:42 +00002044 logger.Debugw(ctx, "UniVlanConfigFsm: Remove EVTOCD set operation",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002045 log.Fields{"configured-flow": oFsm.configuredUniFlow, "incremental-evto": oFsm.acceptIncrementalEvtoOption})
2046 //not transparent and not acceptIncrementalEvtoOption: untagged/priotagged->singletagged
2047 { // just for local var's
2048 // this defines stacking scenario: untagged->singletagged
2049 //TODO!! in theory there could be different rules running in setting different PCP/VID'S
2050 // for untagged/priotagged, last rule wins (and remains the only one), maybe that should be
2051 // checked already at flow-add (and rejected) - to be observed if such is possible in Voltha
2052 // delete now assumes there is only one such rule!
dbainbri4d3a0dc2020-12-02 00:33:42 +00002053 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset untagged rule to default", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002054 "device-id": oFsm.deviceID})
2055 sliceEvtocdRule := make([]uint8, 16)
2056 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2057 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2058 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2059 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2060 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00002061
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002062 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2063 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2064 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2065 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2066 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00002067
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002068 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2069 0<<cTreatTTROffset| // Do not pop any tags
2070 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2071 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2072 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
mpagenko01e726e2020-10-23 09:45:29 +00002073
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002074 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2075 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2076 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2077 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
mpagenko01e726e2020-10-23 09:45:29 +00002078
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002079 meParams := me.ParamData{
2080 EntityID: oFsm.evtocdID,
2081 Attributes: me.AttributeValueMap{
2082 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2083 },
2084 }
Girish Gowdra0b235842021-03-09 13:06:46 -08002085 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002086 oFsm.pAdaptFsm.commChan, meParams)
2087 //accept also nil as (error) return value for writing to LastTx
2088 // - this avoids misinterpretation of new received OMCI messages
2089 oFsm.pLastTxMeInstance = meInstance
2090
2091 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002092 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002093 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002094 logger.Errorw(ctx, "Evtocd reset untagged rule to default failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002095 log.Fields{"device-id": oFsm.deviceID})
2096 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2097 return
2098 }
2099 } // just for local var's
2100 { // just for local var's
2101 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002102 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD delete priotagged rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002103 "device-id": oFsm.deviceID})
2104 sliceEvtocdRule := make([]uint8, 16)
2105 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2106 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2107 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2108 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2109 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2110
2111 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2112 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2113 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2114 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2115 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2116
2117 // delete indication for the indicated Filter
2118 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2119 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2120
2121 meParams := me.ParamData{
2122 EntityID: oFsm.evtocdID,
2123 Attributes: me.AttributeValueMap{
2124 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2125 },
2126 }
Girish Gowdra0b235842021-03-09 13:06:46 -08002127 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002128 oFsm.pAdaptFsm.commChan, meParams)
2129 //accept also nil as (error) return value for writing to LastTx
2130 // - this avoids misinterpretation of new received OMCI messages
2131 oFsm.pLastTxMeInstance = meInstance
2132
2133 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002134 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002135 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002136 logger.Errorw(ctx, "Evtocd delete priotagged rule failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002137 log.Fields{"device-id": oFsm.deviceID})
2138 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2139 return
2140 }
mpagenko01e726e2020-10-23 09:45:29 +00002141 }
2142 } //just for local var's
2143 }
2144 }
2145
mpagenkofc4f56e2020-11-04 17:17:49 +00002146 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002147 logger.Debugw(ctx, "EVTOCD filter remove loop finished", log.Fields{"device-id": oFsm.deviceID})
Girish Gowdra26a40922021-01-29 17:14:34 -08002148 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRemFlowDone, aRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00002149}
2150
dbainbri4d3a0dc2020-12-02 00:33:42 +00002151func (oFsm *UniVlanConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00002152 oFsm.mutexIsAwaitingResponse.Lock()
2153 oFsm.isAwaitingResponse = true
2154 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002155 select {
Himani Chawla26e555c2020-08-31 12:30:20 +05302156 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenkodff5dda2020-08-28 11:52:01 +00002157 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00002158 // logger.Infow(ctx,"LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002159 case <-time.After(30 * time.Second): //AS FOR THE OTHER OMCI FSM's
dbainbri4d3a0dc2020-12-02 00:33:42 +00002160 logger.Warnw(ctx, "UniVlanConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002161 oFsm.mutexIsAwaitingResponse.Lock()
2162 oFsm.isAwaitingResponse = false
2163 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002164 return fmt.Errorf("uniVlanConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002165 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05302166 if success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002167 logger.Debug(ctx, "UniVlanConfigFsm multi entity response received")
mpagenko7d6bb022021-03-11 15:07:55 +00002168 oFsm.mutexIsAwaitingResponse.Lock()
2169 oFsm.isAwaitingResponse = false
2170 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002171 return nil
2172 }
mpagenko7d6bb022021-03-11 15:07:55 +00002173 // waiting was aborted (probably on external request)
2174 logger.Debugw(ctx, "UniVlanConfigFsm wait for multi entity response aborted", log.Fields{"for device-id": oFsm.deviceID})
2175 oFsm.mutexIsAwaitingResponse.Lock()
2176 oFsm.isAwaitingResponse = false
2177 oFsm.mutexIsAwaitingResponse.Unlock()
2178 return fmt.Errorf(cErrWaitAborted)
mpagenkodff5dda2020-08-28 11:52:01 +00002179 }
2180}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002181
mpagenko551a4d42020-12-08 18:09:20 +00002182func (oFsm *UniVlanConfigFsm) performSettingMulticastME(ctx context.Context, tpID uint8, multicastGemPortID uint16, vlanID uint32) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002183 logger.Debugw(ctx, "Setting Multicast MEs", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002184 "multicastGemPortID": multicastGemPortID, "vlanID": vlanID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002185 errCreateMOP := oFsm.performCreatingMulticastOperationProfile(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002186 if errCreateMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002187 logger.Errorw(ctx, "MulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002188 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002189 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002190 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMOP)
2191 }
2192
dbainbri4d3a0dc2020-12-02 00:33:42 +00002193 errSettingMOP := oFsm.performSettingMulticastOperationProfile(ctx, multicastGemPortID, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002194 if errSettingMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002195 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002196 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002197 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002198 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errSettingMOP)
2199 }
2200
dbainbri4d3a0dc2020-12-02 00:33:42 +00002201 errCreateMSCI := oFsm.performCreatingMulticastSubscriberConfigInfo(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002202 if errCreateMSCI != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002203 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002204 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002205 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002206 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMSCI)
2207 }
2208
2209 meParams := me.ParamData{
2210 EntityID: macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo),
2211 Attributes: me.AttributeValueMap{
2212 "BridgeIdPointer": macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo),
2213 "PortNum": 0xf0, //fixed unique ANI side indication
2214 "TpType": 6, //MCGemIWTP
2215 "TpPointer": multicastGemPortID,
2216 },
2217 }
Girish Gowdra0b235842021-03-09 13:06:46 -08002218 meInstance := oFsm.pOmciCC.sendCreateMBPConfigDataVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002219 oFsm.pAdaptFsm.commChan, meParams)
2220 //accept also nil as (error) return value for writing to LastTx
2221 // - this avoids misinterpretation of new received OMCI messages
2222 oFsm.pLastTxMeInstance = meInstance
dbainbri4d3a0dc2020-12-02 00:33:42 +00002223 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002224 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002225 logger.Errorw(ctx, "CreateMBPConfigData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002226 log.Fields{"device-id": oFsm.deviceID, "MBPConfigDataID": macBridgeServiceProfileEID})
mpagenko9a304ea2020-12-16 15:54:01 +00002227 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002228 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, err)
2229 }
2230
2231 // ==> Start creating VTFD for mcast vlan
2232
2233 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
2234 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
2235 mcastVtfdID := macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo)
2236
dbainbri4d3a0dc2020-12-02 00:33:42 +00002237 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD for mcast", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002238 "EntitytId": strconv.FormatInt(int64(mcastVtfdID), 16), "mcastVlanID": vlanID,
2239 "in state": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
2240 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
2241
2242 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
2243 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
2244 // new vlan associated with a different TP.
2245 vtfdFilterList[0] = uint16(vlanID)
2246
2247 meParams = me.ParamData{
2248 EntityID: mcastVtfdID,
2249 Attributes: me.AttributeValueMap{
2250 "VlanFilterList": vtfdFilterList,
2251 "ForwardOperation": uint8(0x10), //VID investigation
2252 "NumberOfEntries": oFsm.numVlanFilterEntries,
2253 },
2254 }
Girish Gowdra0b235842021-03-09 13:06:46 -08002255 meInstance = oFsm.pOmciCC.sendCreateVtfdVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002256 oFsm.pAdaptFsm.commChan, meParams)
2257 oFsm.pLastTxMeInstance = meInstance
dbainbri4d3a0dc2020-12-02 00:33:42 +00002258 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002259 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002260 logger.Errorw(ctx, "CreateMcastVlanFilterData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002261 log.Fields{"device-id": oFsm.deviceID, "mcastVtfdID": mcastVtfdID})
mpagenko9a304ea2020-12-16 15:54:01 +00002262 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002263 return fmt.Errorf("createMcastVlanFilterData responseError %s, error %s", oFsm.deviceID, err)
2264 }
2265
2266 return nil
2267}
2268
dbainbri4d3a0dc2020-12-02 00:33:42 +00002269func (oFsm *UniVlanConfigFsm) performCreatingMulticastSubscriberConfigInfo(ctx context.Context) error {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002270 instID, err := oFsm.pDeviceHandler.getUniPortMEEntityID(oFsm.pOnuUniPort.portNo)
2271 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002272 logger.Errorw(ctx, "error fetching uni port me instance",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002273 log.Fields{"device-id": oFsm.deviceID, "portNo": oFsm.pOnuUniPort.portNo})
2274 return err
2275 }
ozgecanetsia5c88b762021-03-23 10:27:15 +03002276 instID += macBridgePortAniEID
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002277 meParams := me.ParamData{
2278 EntityID: instID,
2279 Attributes: me.AttributeValueMap{
2280 "MeType": 0,
2281 //Direct reference to the Operation profile
2282 //TODO ANI side used on UNI side, not the clearest option.
ozgecanetsia5c88b762021-03-23 10:27:15 +03002283 "MulticastOperationsProfilePointer": instID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002284 },
2285 }
Girish Gowdra0b235842021-03-09 13:06:46 -08002286 meInstance := oFsm.pOmciCC.sendCreateMulticastSubConfigInfoVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002287 oFsm.pAdaptFsm.commChan, meParams)
2288 //accept also nil as (error) return value for writing to LastTx
2289 // - this avoids misinterpretation of new received OMCI messages
2290 oFsm.pLastTxMeInstance = meInstance
2291 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002292 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002293 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002294 logger.Errorw(ctx, "CreateMulticastSubConfigInfo create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002295 log.Fields{"device-id": oFsm.deviceID, "MulticastSubConfigInfo": instID})
2296 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s", oFsm.deviceID)
2297 }
2298 return nil
2299}
2300
dbainbri4d3a0dc2020-12-02 00:33:42 +00002301func (oFsm *UniVlanConfigFsm) performCreatingMulticastOperationProfile(ctx context.Context) error {
ozgecanetsia5c88b762021-03-23 10:27:15 +03002302 instID, err := oFsm.pDeviceHandler.getUniPortMEEntityID(oFsm.pOnuUniPort.portNo)
2303 if err != nil {
2304 logger.Errorw(ctx, "error fetching uni port me instance",
2305 log.Fields{"device-id": oFsm.deviceID, "portNo": oFsm.pOnuUniPort.portNo})
2306 return err
2307 }
2308 instID += macBridgePortAniEID
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002309 meParams := me.ParamData{
2310 EntityID: instID,
2311 Attributes: me.AttributeValueMap{
2312 "IgmpVersion": 2,
2313 "IgmpFunction": 0,
2314 //0 means false
2315 "ImmediateLeave": 0,
2316 "Robustness": 2,
2317 "QuerierIp": 0,
2318 "QueryInterval": 125,
2319 "QuerierMaxResponseTime": 100,
2320 "LastMemberResponseTime": 10,
2321 //0 means false
2322 "UnauthorizedJoinBehaviour": 0,
2323 },
2324 }
Girish Gowdra0b235842021-03-09 13:06:46 -08002325 meInstance := oFsm.pOmciCC.sendCreateMulticastOperationProfileVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002326 oFsm.pAdaptFsm.commChan, meParams)
2327 //accept also nil as (error) return value for writing to LastTx
2328 // - this avoids misinterpretation of new received OMCI messages
2329 oFsm.pLastTxMeInstance = meInstance
2330 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03002331 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002332 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002333 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002334 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
2335 return fmt.Errorf("createMulticastOperationProfile responseError %s", oFsm.deviceID)
2336 }
2337 return nil
2338}
2339
dbainbri4d3a0dc2020-12-02 00:33:42 +00002340func (oFsm *UniVlanConfigFsm) performSettingMulticastOperationProfile(ctx context.Context, multicastGemPortID uint16, vlanID uint32) error {
ozgecanetsia5c88b762021-03-23 10:27:15 +03002341 instID, err := oFsm.pDeviceHandler.getUniPortMEEntityID(oFsm.pOnuUniPort.portNo)
2342 if err != nil {
2343 logger.Errorw(ctx, "error fetching uni port me instance",
2344 log.Fields{"device-id": oFsm.deviceID, "portNo": oFsm.pOnuUniPort.portNo})
2345 return err
2346 }
2347 instID += macBridgePortAniEID
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002348 //TODO check that this is correct
2349 // Table control
2350 //setCtrl = 1
2351 //rowPartId = 0
2352 //test = 0
2353 //rowKey = 0
2354 tableCtrlStr := "0100000000000000"
2355 tableCtrl := AsByteSlice(tableCtrlStr)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002356 dynamicAccessCL := make([]uint8, 24)
2357 copy(dynamicAccessCL, tableCtrl)
2358 //Multicast GemPortId
2359 binary.BigEndian.PutUint16(dynamicAccessCL[2:], multicastGemPortID)
2360 // python version waits for installation of flows, see line 723 onward of
2361 // brcm_openomci_onu_handler.py
2362 binary.BigEndian.PutUint16(dynamicAccessCL[4:], uint16(vlanID))
2363 //Source IP all to 0
2364 binary.BigEndian.PutUint32(dynamicAccessCL[6:], IPToInt32(net.IPv4(0, 0, 0, 0)))
2365 //TODO start and end are hardcoded, get from TP
2366 // Destination IP address start of range
2367 binary.BigEndian.PutUint32(dynamicAccessCL[10:], IPToInt32(net.IPv4(225, 0, 0, 0)))
2368 // Destination IP address end of range
2369 binary.BigEndian.PutUint32(dynamicAccessCL[14:], IPToInt32(net.IPv4(239, 255, 255, 255)))
2370 //imputed group bandwidth
2371 binary.BigEndian.PutUint16(dynamicAccessCL[18:], 0)
2372
2373 meParams := me.ParamData{
2374 EntityID: instID,
2375 Attributes: me.AttributeValueMap{
2376 "DynamicAccessControlListTable": dynamicAccessCL,
2377 },
2378 }
Girish Gowdra0b235842021-03-09 13:06:46 -08002379 meInstance := oFsm.pOmciCC.sendSetMulticastOperationProfileVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002380 oFsm.pAdaptFsm.commChan, meParams)
2381 //accept also nil as (error) return value for writing to LastTx
2382 // - this avoids misinterpretation of new received OMCI messages
2383 oFsm.pLastTxMeInstance = meInstance
2384 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03002385 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002386 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002387 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002388 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
2389 return fmt.Errorf("createMulticastOperationProfile responseError %s", oFsm.deviceID)
2390 }
2391 return nil
2392}
Girish Gowdra26a40922021-01-29 17:14:34 -08002393
2394// IsFlowRemovePending returns true if there are pending flows to remove, else false.
mpagenkobb47bc22021-04-20 13:29:09 +00002395func (oFsm *UniVlanConfigFsm) IsFlowRemovePending(aFlowDeleteChannel chan<- bool) bool {
2396 oFsm.mutexFlowParams.Lock()
2397 defer oFsm.mutexFlowParams.Unlock()
2398 if len(oFsm.uniRemoveFlowsSlice) > 0 {
2399 //flow removal is still ongoing/pending
2400 oFsm.signalOnFlowDelete = true
2401 oFsm.flowDeleteChannel = aFlowDeleteChannel
2402 return true
2403 }
2404 return false
Girish Gowdra26a40922021-01-29 17:14:34 -08002405}