blob: 5d46208276582d55eb57c5be2775002b3af183c0 [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
mpagenkodff5dda2020-08-28 11:52:01 +0000147//UniVlanConfigFsm defines the structure for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
148type UniVlanConfigFsm struct {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530149 pDeviceHandler *deviceHandler
mpagenko01e726e2020-10-23 09:45:29 +0000150 deviceID string
Himani Chawla6d2ae152020-09-02 13:11:20 +0530151 pOmciCC *omciCC
152 pOnuUniPort *onuUniPort
153 pUniTechProf *onuUniTechProf
154 pOnuDB *onuDeviceDB
mpagenkodff5dda2020-08-28 11:52:01 +0000155 requestEvent OnuDeviceEvent
156 omciMIdsResponseReceived chan bool //seperate channel needed for checking multiInstance OMCI message responses
157 pAdaptFsm *AdapterFsm
158 acceptIncrementalEvtoOption bool
mpagenko2418ab02020-11-12 12:58:06 +0000159 clearPersistency bool
mpagenko7d6bb022021-03-11 15:07:55 +0000160 isAwaitingResponse bool
161 mutexIsAwaitingResponse sync.RWMutex
mpagenko551a4d42020-12-08 18:09:20 +0000162 mutexFlowParams sync.RWMutex
mpagenkof1fc3862021-02-16 10:09:52 +0000163 chCookieDeleted chan bool //channel to indicate that a specificly indicated cookie was deleted
mpagenko9a304ea2020-12-16 15:54:01 +0000164 actualUniVlanConfigRule uniVlanRuleParams
mpagenko01e726e2020-10-23 09:45:29 +0000165 uniVlanFlowParamsSlice []uniVlanFlowParams
166 uniRemoveFlowsSlice []uniRemoveVlanFlowParams
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000167 numUniFlows uint8 // expected number of flows should be less than 12
168 configuredUniFlow uint8
mpagenko01e726e2020-10-23 09:45:29 +0000169 numRemoveFlows uint8
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000170 numVlanFilterEntries uint8
mpagenko01e726e2020-10-23 09:45:29 +0000171 vlanFilterList [cVtfdTableSize]uint16
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000172 evtocdID uint16
mpagenko01e726e2020-10-23 09:45:29 +0000173 pLastTxMeInstance *me.ManagedEntity
mpagenkofc4f56e2020-11-04 17:17:49 +0000174 requestEventOffset uint8
mpagenko551a4d42020-12-08 18:09:20 +0000175 TpIDWaitingFor uint8
mpagenkof1fc3862021-02-16 10:09:52 +0000176 //cookie value that indicates that a rule to add is delayed by waiting for deletion of some other existing rule with the same cookie
177 delayNewRuleCookie uint64
mpagenkodff5dda2020-08-28 11:52:01 +0000178}
179
mpagenko01e726e2020-10-23 09:45:29 +0000180//NewUniVlanConfigFsm is the 'constructor' for the state machine to config the PON ANI ports
181// of ONU UNI ports via OMCI
dbainbri4d3a0dc2020-12-02 00:33:42 +0000182func NewUniVlanConfigFsm(ctx context.Context, apDeviceHandler *deviceHandler, apDevOmciCC *omciCC, apUniPort *onuUniPort,
mpagenko551a4d42020-12-08 18:09:20 +0000183 apUniTechProf *onuUniTechProf, apOnuDB *onuDeviceDB, aTechProfileID uint8,
mpagenko01e726e2020-10-23 09:45:29 +0000184 aRequestEvent OnuDeviceEvent, aName string, aCommChannel chan Message, aAcceptIncrementalEvto bool,
185 aCookieSlice []uint64, aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) *UniVlanConfigFsm {
mpagenkodff5dda2020-08-28 11:52:01 +0000186 instFsm := &UniVlanConfigFsm{
187 pDeviceHandler: apDeviceHandler,
mpagenko01e726e2020-10-23 09:45:29 +0000188 deviceID: apDeviceHandler.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +0000189 pOmciCC: apDevOmciCC,
190 pOnuUniPort: apUniPort,
191 pUniTechProf: apUniTechProf,
192 pOnuDB: apOnuDB,
mpagenkodff5dda2020-08-28 11:52:01 +0000193 requestEvent: aRequestEvent,
194 acceptIncrementalEvtoOption: aAcceptIncrementalEvto,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000195 numUniFlows: 0,
196 configuredUniFlow: 0,
mpagenko01e726e2020-10-23 09:45:29 +0000197 numRemoveFlows: 0,
mpagenko2418ab02020-11-12 12:58:06 +0000198 clearPersistency: true,
mpagenkodff5dda2020-08-28 11:52:01 +0000199 }
200
mpagenko01e726e2020-10-23 09:45:29 +0000201 instFsm.pAdaptFsm = NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
mpagenkodff5dda2020-08-28 11:52:01 +0000202 if instFsm.pAdaptFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000203 logger.Errorw(ctx, "UniVlanConfigFsm's AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000204 "device-id": instFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000205 return nil
206 }
mpagenkodff5dda2020-08-28 11:52:01 +0000207 instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
208 vlanStDisabled,
209 fsm.Events{
210 {Name: vlanEvStart, Src: []string{vlanStDisabled}, Dst: vlanStStarting},
211 {Name: vlanEvWaitTechProf, Src: []string{vlanStStarting}, Dst: vlanStWaitingTechProf},
mpagenko535d6ef2021-02-26 13:15:34 +0000212 {Name: vlanEvCancelOutstandingConfig, Src: []string{vlanStWaitingTechProf}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000213 {Name: vlanEvContinueConfig, Src: []string{vlanStWaitingTechProf}, Dst: vlanStConfigVtfd},
214 {Name: vlanEvStartConfig, Src: []string{vlanStStarting}, Dst: vlanStConfigVtfd},
215 {Name: vlanEvRxConfigVtfd, Src: []string{vlanStConfigVtfd}, Dst: vlanStConfigEvtocd},
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000216 {Name: vlanEvRxConfigEvtocd, Src: []string{vlanStConfigEvtocd, vlanStConfigIncrFlow},
217 Dst: vlanStConfigDone},
mpagenko551a4d42020-12-08 18:09:20 +0000218 {Name: vlanEvRenew, Src: []string{vlanStConfigDone}, Dst: vlanStStarting},
219 {Name: vlanEvWaitTPIncr, Src: []string{vlanStConfigDone}, Dst: vlanStIncrFlowWaitTP},
220 {Name: vlanEvIncrFlowConfig, Src: []string{vlanStConfigDone, vlanStIncrFlowWaitTP},
221 Dst: vlanStConfigIncrFlow},
mpagenko01e726e2020-10-23 09:45:29 +0000222 {Name: vlanEvRemFlowConfig, Src: []string{vlanStConfigDone}, Dst: vlanStRemoveFlow},
223 {Name: vlanEvRemFlowDone, Src: []string{vlanStRemoveFlow}, Dst: vlanStCleanupDone},
224 {Name: vlanEvFlowDataRemoved, Src: []string{vlanStCleanupDone}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000225 /*
226 {Name: vlanEvTimeoutSimple, Src: []string{
227 vlanStCreatingDot1PMapper, vlanStCreatingMBPCD, vlanStSettingTconts, vlanStSettingDot1PMapper}, Dst: vlanStStarting},
228 {Name: vlanEvTimeoutMids, Src: []string{
229 vlanStCreatingGemNCTPs, vlanStCreatingGemIWs, vlanStSettingPQs}, Dst: vlanStStarting},
230 */
231 // exceptional treatment for all states except vlanStResetting
232 {Name: vlanEvReset, Src: []string{vlanStStarting, vlanStWaitingTechProf,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000233 vlanStConfigVtfd, vlanStConfigEvtocd, vlanStConfigDone, vlanStConfigIncrFlow,
mpagenko01e726e2020-10-23 09:45:29 +0000234 vlanStRemoveFlow, vlanStCleanupDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000235 Dst: vlanStResetting},
236 // the only way to get to resource-cleared disabled state again is via "resseting"
237 {Name: vlanEvRestart, Src: []string{vlanStResetting}, Dst: vlanStDisabled},
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000238 // transitions for reconcile handling according to VOL-3834
239 {Name: vlanEvSkipOmciConfig, Src: []string{vlanStStarting}, Dst: vlanStConfigDone},
240 {Name: vlanEvSkipOmciConfig, Src: []string{vlanStConfigDone}, Dst: vlanStConfigIncrFlow},
241 {Name: vlanEvSkipIncFlowConfig, Src: []string{vlanStConfigIncrFlow}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000242 },
mpagenkodff5dda2020-08-28 11:52:01 +0000243 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000244 "enter_state": func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(ctx, e) },
245 "enter_" + vlanStStarting: func(e *fsm.Event) { instFsm.enterConfigStarting(ctx, e) },
246 "enter_" + vlanStConfigVtfd: func(e *fsm.Event) { instFsm.enterConfigVtfd(ctx, e) },
247 "enter_" + vlanStConfigEvtocd: func(e *fsm.Event) { instFsm.enterConfigEvtocd(ctx, e) },
248 "enter_" + vlanStConfigDone: func(e *fsm.Event) { instFsm.enterVlanConfigDone(ctx, e) },
249 "enter_" + vlanStConfigIncrFlow: func(e *fsm.Event) { instFsm.enterConfigIncrFlow(ctx, e) },
250 "enter_" + vlanStRemoveFlow: func(e *fsm.Event) { instFsm.enterRemoveFlow(ctx, e) },
251 "enter_" + vlanStCleanupDone: func(e *fsm.Event) { instFsm.enterVlanCleanupDone(ctx, e) },
252 "enter_" + vlanStResetting: func(e *fsm.Event) { instFsm.enterResetting(ctx, e) },
253 "enter_" + vlanStDisabled: func(e *fsm.Event) { instFsm.enterDisabled(ctx, e) },
mpagenkodff5dda2020-08-28 11:52:01 +0000254 },
255 )
256 if instFsm.pAdaptFsm.pFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000257 logger.Errorw(ctx, "UniVlanConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000258 "device-id": instFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000259 return nil
260 }
261
dbainbri4d3a0dc2020-12-02 00:33:42 +0000262 _ = instFsm.initUniFlowParams(ctx, aTechProfileID, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000263
dbainbri4d3a0dc2020-12-02 00:33:42 +0000264 logger.Debugw(ctx, "UniVlanConfigFsm created", log.Fields{"device-id": instFsm.deviceID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000265 "accIncrEvto": instFsm.acceptIncrementalEvtoOption})
mpagenkodff5dda2020-08-28 11:52:01 +0000266 return instFsm
267}
268
mpagenko01e726e2020-10-23 09:45:29 +0000269//initUniFlowParams is a simplified form of SetUniFlowParams() used for first flow parameters configuration
mpagenko551a4d42020-12-08 18:09:20 +0000270func (oFsm *UniVlanConfigFsm) initUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +0000271 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) error {
272 loRuleParams := uniVlanRuleParams{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000273 TpID: aTpID,
274 MatchVid: uint32(aMatchVlan),
275 SetVid: uint32(aSetVlan),
276 SetPcp: uint32(aSetPcp),
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000277 }
278 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
mpagenko01e726e2020-10-23 09:45:29 +0000279 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
280 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000281
mpagenko01e726e2020-10-23 09:45:29 +0000282 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000283 //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 +0000284 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000285 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
286 } else {
287 if !oFsm.acceptIncrementalEvtoOption {
288 //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 +0000289 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000290 }
291 }
292
mpagenko01e726e2020-10-23 09:45:29 +0000293 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000294 // no prio/vid filtering requested
mpagenko01e726e2020-10-23 09:45:29 +0000295 loRuleParams.TagsToRemove = 0 //no tag pop action
296 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
297 if loRuleParams.SetPcp == cCopyPrioFromInner {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000298 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
299 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
300 // might collide with NoMatchVid/CopyPrio(/setVid) setting
301 // this was some precondition setting taken over from py adapter ..
mpagenko01e726e2020-10-23 09:45:29 +0000302 loRuleParams.SetPcp = 0
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000303 }
304 }
mpagenko01e726e2020-10-23 09:45:29 +0000305
306 loFlowParams := uniVlanFlowParams{VlanRuleParams: loRuleParams}
307 loFlowParams.CookieSlice = make([]uint64, 0)
308 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
309
310 //no mutex protection is required for initial access and adding the first flow is always possible
311 oFsm.uniVlanFlowParamsSlice = make([]uniVlanFlowParams, 0)
312 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000313 logger.Debugw(ctx, "first UniVlanConfigFsm flow added", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000314 "Cookies": oFsm.uniVlanFlowParamsSlice[0].CookieSlice,
315 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
316 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
317 "SetPcp": loRuleParams.SetPcp,
318 "device-id": oFsm.deviceID})
319 oFsm.numUniFlows = 1
320 oFsm.uniRemoveFlowsSlice = make([]uniRemoveVlanFlowParams, 0) //initially nothing to remove
321
322 //permanently store flow config for reconcile case
dbainbri4d3a0dc2020-12-02 00:33:42 +0000323 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
mpagenkof1fc3862021-02-16 10:09:52 +0000324 &oFsm.uniVlanFlowParamsSlice, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000325 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000326 return err
327 }
328
329 return nil
330}
331
mpagenko7d6bb022021-03-11 15:07:55 +0000332//CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
333func (oFsm *UniVlanConfigFsm) CancelProcessing() {
334 //mutex protection is required for possible concurrent access to FSM members
335 oFsm.mutexIsAwaitingResponse.RLock()
336 defer oFsm.mutexIsAwaitingResponse.RUnlock()
337 if oFsm.isAwaitingResponse {
338 //use channel to indicate that the response waiting shall be aborted
339 oFsm.omciMIdsResponseReceived <- false
340 }
341 // in any case (even if it might be automatically requested by above cancellation of waiting) ensure resetting the FSM
342 pAdaptFsm := oFsm.pAdaptFsm
343 if pAdaptFsm != nil {
344 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
345 go func(aPAFsm *AdapterFsm) {
346 if aPAFsm.pFsm != nil {
347 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
348 }
349 }(pAdaptFsm)
350 }
351}
352
mpagenko551a4d42020-12-08 18:09:20 +0000353//GetWaitingTpID returns the TpId that the FSM might be waiting for continuation (0 if none)
354func (oFsm *UniVlanConfigFsm) GetWaitingTpID() uint8 {
355 //mutex protection is required for possible concurrent access to FSM members
356 oFsm.mutexFlowParams.RLock()
357 defer oFsm.mutexFlowParams.RUnlock()
358 return oFsm.TpIDWaitingFor
359}
360
mpagenko2418ab02020-11-12 12:58:06 +0000361//RequestClearPersistency sets the internal flag to not clear persistency data (false=NoClear)
362func (oFsm *UniVlanConfigFsm) RequestClearPersistency(aClear bool) {
363 //mutex protection is required for possible concurrent access to FSM members
mpagenko15ff4a52021-03-02 10:09:20 +0000364 oFsm.mutexFlowParams.Lock()
365 defer oFsm.mutexFlowParams.Unlock()
mpagenko2418ab02020-11-12 12:58:06 +0000366 oFsm.clearPersistency = aClear
367}
368
mpagenko01e726e2020-10-23 09:45:29 +0000369//SetUniFlowParams verifies on existence of flow parameters to be configured,
370// optionally udates the cookie list or appends a new flow if there is space
371// if possible the FSM is trigggerd to start with the processing
mpagenko551a4d42020-12-08 18:09:20 +0000372// ignore complexity by now
373// nolint: gocyclo
374func (oFsm *UniVlanConfigFsm) SetUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +0000375 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) error {
376 loRuleParams := uniVlanRuleParams{
377 TpID: aTpID,
378 MatchVid: uint32(aMatchVlan),
379 SetVid: uint32(aSetVlan),
380 SetPcp: uint32(aSetPcp),
381 }
382 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
383 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
384 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
385
386 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
387 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
388 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
389 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
390 } else {
391 if !oFsm.acceptIncrementalEvtoOption {
392 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
393 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
394 }
395 }
396
397 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
398 // no prio/vid filtering requested
399 loRuleParams.TagsToRemove = 0 //no tag pop action
400 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
401 if loRuleParams.SetPcp == cCopyPrioFromInner {
402 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
403 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
404 // might collide with NoMatchVid/CopyPrio(/setVid) setting
405 // this was some precondition setting taken over from py adapter ..
406 loRuleParams.SetPcp = 0
407 }
408 }
409
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000410 flowEntryMatch := false
mpagenko01e726e2020-10-23 09:45:29 +0000411 flowCookieModify := false
mpagenkof1fc3862021-02-16 10:09:52 +0000412 requestAppendRule := false
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000413 //mutex protection is required for possible concurrent access to FSM members
414 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +0000415 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
416 //TODO: Verify if using e.g. hashes for the structures here for comparison may generate
417 // countable run time optimization (perhaps with including the hash in kvStore storage?)
418 if storedUniFlowParams.VlanRuleParams == loRuleParams {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000419 flowEntryMatch = true
dbainbri4d3a0dc2020-12-02 00:33:42 +0000420 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - rule already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000421 "device-id": oFsm.deviceID})
422 var cookieMatch bool
423 for _, newCookie := range aCookieSlice { // for all cookies available in the arguments
424 cookieMatch = false
425 for _, cookie := range storedUniFlowParams.CookieSlice {
426 if cookie == newCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000427 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - and cookie already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000428 "device-id": oFsm.deviceID, "cookie": cookie})
429 cookieMatch = true
430 break //found new cookie - no further search for this requested cookie
431 }
432 }
433 if !cookieMatch {
mpagenkof1fc3862021-02-16 10:09:52 +0000434 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
435 if delayedCookie != 0 {
436 //a delay for adding the cookie to this rule is requested
437 // take care of the mutex which is already locked here, need to unlock/lock accordingly to prevent deadlock in suspension
438 oFsm.mutexFlowParams.Unlock()
439 oFsm.suspendNewRule(ctx)
440 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
441 oFsm.mutexFlowParams.Lock()
442 } else {
443 logger.Debugw(ctx, "UniVlanConfigFsm flow setting -adding new cookie", log.Fields{
444 "device-id": oFsm.deviceID, "cookie": newCookie})
445 //as range works with copies of the slice we have to write to the original slice!!
446 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
447 newCookie)
448 flowCookieModify = true
449 }
mpagenko01e726e2020-10-23 09:45:29 +0000450 }
451 } //for all new cookies
452 break // found rule - no further rule search
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000453 }
454 }
mpagenkof1fc3862021-02-16 10:09:52 +0000455 oFsm.mutexFlowParams.Unlock()
456
457 if !flowEntryMatch { //it is (was) a new rule
458 delayedCookie := oFsm.suspendIfRequiredNewRule(ctx, aCookieSlice)
459 requestAppendRule = true //default assumption here is that rule is to be appended
460 flowCookieModify = true //and that the the flow data base is to be updated
461 if delayedCookie != 0 { //it was suspended
462 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
463 }
464 }
465 kvStoreWrite := false //default setting is to not write to kvStore immediately - will be done on FSM execution finally
466 if requestAppendRule {
467 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000468 if oFsm.numUniFlows < cMaxAllowedFlows {
mpagenko01e726e2020-10-23 09:45:29 +0000469 loFlowParams := uniVlanFlowParams{VlanRuleParams: loRuleParams}
470 loFlowParams.CookieSlice = make([]uint64, 0)
471 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
472 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000473 logger.Debugw(ctx, "UniVlanConfigFsm flow add", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000474 "Cookies": oFsm.uniVlanFlowParamsSlice[oFsm.numUniFlows].CookieSlice,
475 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
476 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
Girish Gowdra041dcb32020-11-16 16:54:30 -0800477 "SetPcp": loRuleParams.SetPcp, "numberofFlows": oFsm.numUniFlows + 1,
mpagenko01e726e2020-10-23 09:45:29 +0000478 "device-id": oFsm.deviceID})
479
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000480 oFsm.numUniFlows++
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000481 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
482
483 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
484 logger.Debugw(ctx, "reconciling - skip omci-config of additional vlan rule",
485 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
486 oFsm.mutexFlowParams.Unlock()
487 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
488 go func(a_pBaseFsm *fsm.FSM) {
489 _ = a_pBaseFsm.Event(vlanEvSkipOmciConfig)
490 }(pConfigVlanStateBaseFsm)
491 }
492 return nil
493 }
mpagenko01e726e2020-10-23 09:45:29 +0000494 // note: theoretical it would be possible to clear the same rule from the remove slice
495 // (for entries that have not yet been started with removal)
496 // but that is getting quite complicated - maybe a future optimization in case it should prove reasonable
497 // 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 +0000498
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000499 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
500 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
mpagenko551a4d42020-12-08 18:09:20 +0000501 if oFsm.configuredUniFlow == 0 {
502 // this is a restart with a complete new flow, we can re-use the initial flow config control
503 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenko9a304ea2020-12-16 15:54:01 +0000504 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +0000505 go func(a_pBaseFsm *fsm.FSM) {
506 _ = a_pBaseFsm.Event(vlanEvRenew)
507 }(pConfigVlanStateBaseFsm)
508 } else {
509 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000510 //store the actual rule that shall be worked upon in the following transient states
511 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +0000512 //tpId of the next rule to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000513 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko551a4d42020-12-08 18:09:20 +0000514 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, tpID)
515 oFsm.TpIDWaitingFor = tpID
mpagenko9a304ea2020-12-16 15:54:01 +0000516 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request (on setConfig)", log.Fields{
517 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
518 "set-Vlan": oFsm.actualUniVlanConfigRule.SetVid, "tp-id": tpID, "ProfDone": loTechProfDone})
519
mpagenko551a4d42020-12-08 18:09:20 +0000520 go func(aPBaseFsm *fsm.FSM, aTechProfDone bool) {
521 if aTechProfDone {
522 // let the vlan processing continue with next rule
523 _ = aPBaseFsm.Event(vlanEvIncrFlowConfig)
524 } else {
525 // set to waiting for Techprofile
526 _ = aPBaseFsm.Event(vlanEvWaitTPIncr)
527 }
528 }(pConfigVlanStateBaseFsm, loTechProfDone)
529 }
mpagenko01e726e2020-10-23 09:45:29 +0000530 } // if not in the appropriate state a new entry will be automatically considered later
531 // when the configDone state is reached
mpagenko15ff4a52021-03-02 10:09:20 +0000532 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000533 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000534 logger.Errorw(ctx, "UniVlanConfigFsm flow limit exceeded", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000535 "device-id": oFsm.deviceID, "flow-number": oFsm.numUniFlows})
mpagenko15ff4a52021-03-02 10:09:20 +0000536 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000537 return fmt.Errorf(" UniVlanConfigFsm flow limit exceeded %s", oFsm.deviceID)
538 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000539 } else {
540 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
mpagenkof1fc3862021-02-16 10:09:52 +0000541 kvStoreWrite = true // ensure actual data write to kvStore immediately (no FSM activity)
mpagenko15ff4a52021-03-02 10:09:20 +0000542 oFsm.mutexFlowParams.RLock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000543 if oFsm.numUniFlows == oFsm.configuredUniFlow {
544 //all requested rules really have been configured
545 // state transition notification is checked in deviceHandler
mpagenko15ff4a52021-03-02 10:09:20 +0000546 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000547 if oFsm.pDeviceHandler != nil {
548 //also the related TechProfile was already configured
dbainbri4d3a0dc2020-12-02 00:33:42 +0000549 logger.Debugw(ctx, "UniVlanConfigFsm rule already set - send immediate add-success event for reason update", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +0000550 "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +0000551 // success indication without the need to write to kvStore (done already below with updated data from storePersUniFlowConfig())
552 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetAddNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000553 }
554 } else {
555 // avoid device reason update as the rule config connected to this flow may still be in progress
556 // and the device reason should only be updated on success of rule config
dbainbri4d3a0dc2020-12-02 00:33:42 +0000557 logger.Debugw(ctx, "UniVlanConfigFsm rule already set but configuration ongoing, suppress early add-success event for reason update",
mpagenkofc4f56e2020-11-04 17:17:49 +0000558 log.Fields{"device-id": oFsm.deviceID,
559 "NumberofRules": oFsm.numUniFlows, "Configured rules": oFsm.configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +0000560 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000561 }
562 }
mpagenko01e726e2020-10-23 09:45:29 +0000563
mpagenkof1fc3862021-02-16 10:09:52 +0000564 if flowCookieModify { // some change was done to the flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000565 //permanently store flow config for reconcile case
mpagenko15ff4a52021-03-02 10:09:20 +0000566 oFsm.mutexFlowParams.RLock()
mpagenkof1fc3862021-02-16 10:09:52 +0000567 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
568 &oFsm.uniVlanFlowParamsSlice, kvStoreWrite); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +0000569 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000570 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000571 return err
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000572 }
mpagenko15ff4a52021-03-02 10:09:20 +0000573 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000574 }
575 return nil
576}
577
mpagenkof1fc3862021-02-16 10:09:52 +0000578// VOL-3828 flow config sequence workaround ########### start ##########
579func (oFsm *UniVlanConfigFsm) delayNewRuleForCookie(ctx context.Context, aCookieSlice []uint64) uint64 {
580 //assumes mutexFlowParams.Lock() protection from caller!
581 if oFsm.delayNewRuleCookie == 0 && len(aCookieSlice) == 1 {
582 // if not already waiting, limitation for this workaround is to just have one overlapping cookie/rule
583 // suspend check is done only of there is only one cookie in the request
584 // background: more elements only expected in reconcile use case, where no conflicting sequence is to be expected
585 newCookie := aCookieSlice[0]
586 for _, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
587 for _, cookie := range storedUniFlowParams.CookieSlice {
588 if cookie == newCookie {
589 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - new cookie still exists for some rule", log.Fields{
590 "device-id": oFsm.deviceID, "cookie": cookie, "exists with SetVlan": storedUniFlowParams.VlanRuleParams.SetVid})
591 oFsm.delayNewRuleCookie = newCookie
592 return newCookie //found new cookie in some existing rule
593 }
594 } // for all stored cookies of the actual inspected rule
595 } //for all rules
596 }
597 return 0 //no delay requested
598}
599func (oFsm *UniVlanConfigFsm) suspendNewRule(ctx context.Context) {
600 oFsm.mutexFlowParams.RLock()
601 logger.Infow(ctx, "Need to suspend adding this rule as long as the cookie is still connected to some other rule", log.Fields{
602 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
603 oFsm.mutexFlowParams.RUnlock()
604 select {
605 case <-oFsm.chCookieDeleted:
606 logger.Infow(ctx, "resume adding this rule after having deleted cookie in some other rule", log.Fields{
607 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
608 case <-time.After(time.Duration(cWaitForCookieDeletion) * time.Second):
609 logger.Errorw(ctx, "timeout waiting for deletion of cookie in some other rule, just try to continue", log.Fields{
610 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
611 }
612 oFsm.mutexFlowParams.Lock()
613 oFsm.delayNewRuleCookie = 0
614 oFsm.mutexFlowParams.Unlock()
615}
616func (oFsm *UniVlanConfigFsm) suspendIfRequiredNewRule(ctx context.Context, aCookieSlice []uint64) uint64 {
617 oFsm.mutexFlowParams.Lock()
618 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
619 oFsm.mutexFlowParams.Unlock()
620
621 if delayedCookie != 0 {
622 oFsm.suspendNewRule(ctx)
623 }
624 return delayedCookie
625}
626
627//returns flowModified, RuleAppendRequest
628func (oFsm *UniVlanConfigFsm) reviseFlowConstellation(ctx context.Context, aCookie uint64, aUniVlanRuleParams uniVlanRuleParams) (bool, bool) {
629 flowEntryMatch := false
630 oFsm.mutexFlowParams.Lock()
631 defer oFsm.mutexFlowParams.Unlock()
632 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
633 if storedUniFlowParams.VlanRuleParams == aUniVlanRuleParams {
634 flowEntryMatch = true
635 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - rule already exists", log.Fields{
636 "device-id": oFsm.deviceID})
637 cookieMatch := false
638 for _, cookie := range storedUniFlowParams.CookieSlice {
639 if cookie == aCookie {
640 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - and cookie already exists", log.Fields{
641 "device-id": oFsm.deviceID, "cookie": cookie})
642 cookieMatch = true
643 break //found new cookie - no further search for this requested cookie
644 }
645 }
646 if !cookieMatch {
647 logger.Debugw(ctx, "UniVlanConfigFsm flow revise -adding new cookie", log.Fields{
648 "device-id": oFsm.deviceID, "cookie": aCookie})
649 //as range works with copies of the slice we have to write to the original slice!!
650 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
651 aCookie)
652 return true, false //flowModified, NoRuleAppend
653 }
654 break // found rule - no further rule search
655 }
656 }
657 if !flowEntryMatch { //it is a new rule
658 return true, true //flowModified, RuleAppend
659 }
660 return false, false //flowNotModified, NoRuleAppend
661}
662
663// VOL-3828 flow config sequence workaround ########### end ##########
664
mpagenko01e726e2020-10-23 09:45:29 +0000665//RemoveUniFlowParams verifies on existence of flow cookie,
666// if found removes cookie from flow cookie list and if this is empty
667// initiates removal of the flow related configuration from the ONU (via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000668func (oFsm *UniVlanConfigFsm) RemoveUniFlowParams(ctx context.Context, aCookie uint64) error {
mpagenkof1fc3862021-02-16 10:09:52 +0000669 var deletedCookie uint64
mpagenko01e726e2020-10-23 09:45:29 +0000670 flowCookieMatch := false
671 //mutex protection is required for possible concurrent access to FSM members
672 oFsm.mutexFlowParams.Lock()
673 defer oFsm.mutexFlowParams.Unlock()
mpagenkof1fc3862021-02-16 10:09:52 +0000674remove_loop:
mpagenko01e726e2020-10-23 09:45:29 +0000675 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
676 for i, cookie := range storedUniFlowParams.CookieSlice {
677 if cookie == aCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000678 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - cookie found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000679 "device-id": oFsm.deviceID, "cookie": cookie})
680 flowCookieMatch = true
mpagenkof1fc3862021-02-16 10:09:52 +0000681 deletedCookie = aCookie
682 kvStoreWrite := false //default setting is to not write to kvStore immediately - will be done on FSM execution finally
mpagenko01e726e2020-10-23 09:45:29 +0000683 //remove the cookie from the cookie slice and verify it is getting empty
684 if len(storedUniFlowParams.CookieSlice) == 1 {
mpagenko535d6ef2021-02-26 13:15:34 +0000685 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
686 var cancelPendingConfig bool = false
687 var loRemoveParams uniRemoveVlanFlowParams = uniRemoveVlanFlowParams{}
dbainbri4d3a0dc2020-12-02 00:33:42 +0000688 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - full flow removal", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000689 "device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +0000690 //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 +0000691 // as the one still waiting in the FSM as toAdd but waiting for TechProfileConfig
mpagenko15ff4a52021-03-02 10:09:20 +0000692 // 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 +0000693 // if the Fsm is in some other transient (config) state, we will reach the DelRequest later and correctly process it then
694 if pConfigVlanStateBaseFsm.Is(vlanStWaitingTechProf) {
695 logger.Debugw(ctx, "UniVlanConfigFsm was waiting for TechProf config with this rule, aborting the outstanding config",
696 log.Fields{"device-id": oFsm.deviceID})
697 cancelPendingConfig = true
698 } else {
699 //create a new element for the removeVlanFlow slice
700 loRemoveParams = uniRemoveVlanFlowParams{
701 vlanRuleParams: storedUniFlowParams.VlanRuleParams,
702 cookie: aCookie,
703 }
704 oFsm.uniRemoveFlowsSlice = append(oFsm.uniRemoveFlowsSlice, loRemoveParams)
mpagenko01e726e2020-10-23 09:45:29 +0000705 }
mpagenko01e726e2020-10-23 09:45:29 +0000706
707 //and remove the actual element from the addVlanFlow slice
708 // oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = nil //automatically done by garbage collector
709 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
710 oFsm.numUniFlows = 0 //no more flows
711 oFsm.configuredUniFlow = 0 //no more flows configured
712 oFsm.uniVlanFlowParamsSlice = nil //reset the slice
mpagenko2418ab02020-11-12 12:58:06 +0000713 //at this point it is evident that no flow anymore refers to a still possibly active Techprofile
mpagenko535d6ef2021-02-26 13:15:34 +0000714 //request that this profile gets deleted before a new flow add is allowed (except for some aborted add)
715 if !cancelPendingConfig {
716 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, loRemoveParams.vlanRuleParams.TpID, true)
717 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000718 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - no more flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000719 "device-id": oFsm.deviceID})
720 } else {
721 oFsm.numUniFlows--
722 if oFsm.configuredUniFlow > 0 {
723 oFsm.configuredUniFlow--
724 //TODO!! might be needed to consider still outstanding configure requests ..
725 // so a flow at removal might still not be configured !?!
726 }
mpagenko2418ab02020-11-12 12:58:06 +0000727 usedTpID := storedUniFlowParams.VlanRuleParams.TpID
mpagenko01e726e2020-10-23 09:45:29 +0000728 //cut off the requested flow by slicing out this element
729 oFsm.uniVlanFlowParamsSlice = append(
730 oFsm.uniVlanFlowParamsSlice[:flow], oFsm.uniVlanFlowParamsSlice[flow+1:]...)
mpagenko2418ab02020-11-12 12:58:06 +0000731 //here we have to check, if there are still other flows referencing to the actual ProfileId
732 // before we can request that this profile gets deleted before a new flow add is allowed
mpagenkof1fc3862021-02-16 10:09:52 +0000733 // (needed to extract to function due to lint complexity)
mpagenko535d6ef2021-02-26 13:15:34 +0000734 if !cancelPendingConfig {
735 oFsm.updateTechProfileToDelete(ctx, usedTpID)
736 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000737 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow removed from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000738 "device-id": oFsm.deviceID})
739 }
740 //trigger the FSM to remove the relevant rule
mpagenko535d6ef2021-02-26 13:15:34 +0000741 if cancelPendingConfig {
742 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
mpagenko01e726e2020-10-23 09:45:29 +0000743 go func(a_pBaseFsm *fsm.FSM) {
mpagenko535d6ef2021-02-26 13:15:34 +0000744 _ = a_pBaseFsm.Event(vlanEvCancelOutstandingConfig)
mpagenko01e726e2020-10-23 09:45:29 +0000745 }(pConfigVlanStateBaseFsm)
mpagenko535d6ef2021-02-26 13:15:34 +0000746 } else {
747 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
748 logger.Debugw(ctx, "UniVlanConfigFsm rule removal request", log.Fields{
749 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
750 "tp-id": loRemoveParams.vlanRuleParams.TpID,
751 "set-Vlan": loRemoveParams.vlanRuleParams.SetVid})
752 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
753 // Can't call FSM Event directly, decoupling it
754 go func(a_pBaseFsm *fsm.FSM) {
755 _ = a_pBaseFsm.Event(vlanEvRemFlowConfig)
756 }(pConfigVlanStateBaseFsm)
757 } // if not in the appropriate state a new entry will be automatically considered later
758 // when the configDone state is reached
759 }
mpagenko01e726e2020-10-23 09:45:29 +0000760 } else {
mpagenko01e726e2020-10-23 09:45:29 +0000761 //cut off the requested cookie by slicing out this element
762 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(
763 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[:i],
764 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[i+1:]...)
mpagenkofc4f56e2020-11-04 17:17:49 +0000765 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
mpagenkof1fc3862021-02-16 10:09:52 +0000766 kvStoreWrite = true // ensure actual data write to kvStore immediately (no FSM activity)
mpagenkofc4f56e2020-11-04 17:17:49 +0000767 // state transition notification is checked in deviceHandler
768 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000769 // success indication without the need to write to kvStore (done already below with updated data from storePersUniFlowConfig())
770 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000771 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000772 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - rule persists with still valid cookies", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000773 "device-id": oFsm.deviceID, "cookies": oFsm.uniVlanFlowParamsSlice[flow].CookieSlice})
mpagenkof1fc3862021-02-16 10:09:52 +0000774 if deletedCookie == oFsm.delayNewRuleCookie {
775 //the delayedNewCookie is the one that is currently deleted, but the rule still exist with other cookies
776 //as long as there are further cookies for this rule indicate there is still some cookie to be deleted
777 //simply use the first one
778 oFsm.delayNewRuleCookie = oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[0]
779 logger.Debugw(ctx, "UniVlanConfigFsm remaining cookie awaited for deletion before new rule add", log.Fields{
780 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
781 }
mpagenko01e726e2020-10-23 09:45:29 +0000782 }
mpagenko01e726e2020-10-23 09:45:29 +0000783 //permanently store the modified flow config for reconcile case
mpagenkofc4f56e2020-11-04 17:17:49 +0000784 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000785 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
786 &oFsm.uniVlanFlowParamsSlice, kvStoreWrite); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000787 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +0000788 return err
789 }
mpagenko01e726e2020-10-23 09:45:29 +0000790 }
mpagenkof1fc3862021-02-16 10:09:52 +0000791 break remove_loop //found the cookie - no further search for this requested cookie
mpagenko01e726e2020-10-23 09:45:29 +0000792 }
793 }
mpagenko01e726e2020-10-23 09:45:29 +0000794 } //search all flows
795 if !flowCookieMatch { //some cookie remove-request for a cookie that does not exist in the FSM data
dbainbri4d3a0dc2020-12-02 00:33:42 +0000796 logger.Warnw(ctx, "UniVlanConfigFsm flow removal - remove-cookie not found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000797 "device-id": oFsm.deviceID, "remove-cookie": aCookie})
798 // but accept the request with success as no such cookie (flow) does exist
mpagenkofc4f56e2020-11-04 17:17:49 +0000799 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
800 // state transition notification is checked in deviceHandler
801 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000802 // success indication without the need to write to kvStore (no change)
803 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000804 }
mpagenko01e726e2020-10-23 09:45:29 +0000805 return nil
806 } //unknown cookie
807
808 return nil
809}
810
mpagenkof1fc3862021-02-16 10:09:52 +0000811func (oFsm *UniVlanConfigFsm) updateTechProfileToDelete(ctx context.Context, usedTpID uint8) {
812 //here we have to check, if there are still other flows referencing to the actual ProfileId
813 // before we can request that this profile gets deleted before a new flow add is allowed
814 tpIDInOtherFlows := false
815 for _, tpUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
816 if tpUniFlowParams.VlanRuleParams.TpID == usedTpID {
817 tpIDInOtherFlows = true
818 break // search loop can be left
819 }
820 }
821 if tpIDInOtherFlows {
822 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is still used in other flows", log.Fields{
823 "device-id": oFsm.deviceID, "tp-id": usedTpID})
824 } else {
825 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is not used anymore", log.Fields{
826 "device-id": oFsm.deviceID, "tp-id": usedTpID})
827 //request that this profile gets deleted before a new flow add is allowed
828 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, usedTpID, true)
829 }
830}
831
dbainbri4d3a0dc2020-12-02 00:33:42 +0000832func (oFsm *UniVlanConfigFsm) enterConfigStarting(ctx context.Context, e *fsm.Event) {
833 logger.Debugw(ctx, "UniVlanConfigFsm start", log.Fields{"in state": e.FSM.Current(),
mpagenko01e726e2020-10-23 09:45:29 +0000834 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000835
836 // this FSM is not intended for re-start, needs always new creation for a new run
mpagenko01e726e2020-10-23 09:45:29 +0000837 // (self-destroying - compare enterDisabled())
mpagenkodff5dda2020-08-28 11:52:01 +0000838 oFsm.omciMIdsResponseReceived = make(chan bool)
mpagenkof1fc3862021-02-16 10:09:52 +0000839 oFsm.chCookieDeleted = make(chan bool)
mpagenkodff5dda2020-08-28 11:52:01 +0000840 // start go routine for processing of LockState messages
dbainbri4d3a0dc2020-12-02 00:33:42 +0000841 go oFsm.processOmciVlanMessages(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +0000842 //let the state machine run forward from here directly
843 pConfigVlanStateAFsm := oFsm.pAdaptFsm
844 if pConfigVlanStateAFsm != nil {
mpagenko9a304ea2020-12-16 15:54:01 +0000845
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000846 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
847 logger.Debugw(ctx, "reconciling - skip omci-config of vlan rule",
848 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
849 go func(a_pAFsm *AdapterFsm) {
850 _ = a_pAFsm.pFsm.Event(vlanEvSkipOmciConfig)
851 }(pConfigVlanStateAFsm)
852 return
853 }
854 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +0000855 //possibly the entry is not valid anymore based on intermediate delete requests
856 //just a basic protection ...
857 if len(oFsm.uniVlanFlowParamsSlice) == 0 {
858 oFsm.mutexFlowParams.Unlock()
859 logger.Debugw(ctx, "UniVlanConfigFsm start: no rule entry anymore available", log.Fields{
860 "device-id": oFsm.deviceID})
861 // Can't call FSM Event directly, decoupling it
862 go func(a_pAFsm *AdapterFsm) {
863 _ = a_pAFsm.pFsm.Event(vlanEvReset)
864 }(pConfigVlanStateAFsm)
865 return
866 }
mpagenko9a304ea2020-12-16 15:54:01 +0000867 //access to uniVlanFlowParamsSlice is done on first element only here per definition
868 //store the actual rule that shall be worked upon in the following transient states
869 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[0].VlanRuleParams
mpagenko9a304ea2020-12-16 15:54:01 +0000870 tpID := oFsm.actualUniVlanConfigRule.TpID
871 oFsm.TpIDWaitingFor = tpID
mpagenko551a4d42020-12-08 18:09:20 +0000872 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID))
mpagenko9a304ea2020-12-16 15:54:01 +0000873 logger.Debugw(ctx, "UniVlanConfigFsm - start with first rule", log.Fields{
874 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
875 "set-Vlan": oFsm.actualUniVlanConfigRule.SetVid, "tp-id": tpID, "ProfDone": loTechProfDone})
mpagenko551a4d42020-12-08 18:09:20 +0000876 //cmp also usage in EVTOCDE create in omci_cc
877 oFsm.evtocdID = macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo)
mpagenko535d6ef2021-02-26 13:15:34 +0000878 oFsm.mutexFlowParams.Unlock()
mpagenko9a304ea2020-12-16 15:54:01 +0000879 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +0000880 go func(aPAFsm *AdapterFsm, aTechProfDone bool) {
881 if aPAFsm != nil && aPAFsm.pFsm != nil {
882 if aTechProfDone {
mpagenkodff5dda2020-08-28 11:52:01 +0000883 // let the vlan processing begin
mpagenko551a4d42020-12-08 18:09:20 +0000884 _ = aPAFsm.pFsm.Event(vlanEvStartConfig)
mpagenkodff5dda2020-08-28 11:52:01 +0000885 } else {
886 // set to waiting for Techprofile
mpagenko551a4d42020-12-08 18:09:20 +0000887 _ = aPAFsm.pFsm.Event(vlanEvWaitTechProf)
mpagenkodff5dda2020-08-28 11:52:01 +0000888 }
889 }
mpagenko551a4d42020-12-08 18:09:20 +0000890 }(pConfigVlanStateAFsm, loTechProfDone)
891 } else {
892 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
893 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
894 //should never happen, else: recovery would be needed from outside the FSM
895 return
mpagenkodff5dda2020-08-28 11:52:01 +0000896 }
897}
898
dbainbri4d3a0dc2020-12-02 00:33:42 +0000899func (oFsm *UniVlanConfigFsm) enterConfigVtfd(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000900 //mutex protection is required for possible concurrent access to FSM members
901 oFsm.mutexFlowParams.Lock()
mpagenko551a4d42020-12-08 18:09:20 +0000902 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
mpagenko9a304ea2020-12-16 15:54:01 +0000903 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +0000904 // meaning transparent setup - no specific VTFD setting required
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000905 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000906 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000907 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000908 // let the FSM proceed ... (from within this state all internal pointers may be expected to be correct)
mpagenkodff5dda2020-08-28 11:52:01 +0000909 pConfigVlanStateAFsm := oFsm.pAdaptFsm
mpagenko9a304ea2020-12-16 15:54:01 +0000910 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +0000911 go func(a_pAFsm *AdapterFsm) {
Himani Chawla4d908332020-08-31 12:30:20 +0530912 _ = a_pAFsm.pFsm.Event(vlanEvRxConfigVtfd)
mpagenkodff5dda2020-08-28 11:52:01 +0000913 }(pConfigVlanStateAFsm)
914 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300915 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
916 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
mpagenko9a304ea2020-12-16 15:54:01 +0000917 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + uint16(oFsm.actualUniVlanConfigRule.TpID)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000918 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300919 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000920 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
921 // setVid is assumed to be masked already by the caller to 12 bit
mpagenko9a304ea2020-12-16 15:54:01 +0000922 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000923 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000924 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000925 vtfdFilterList[0] = oFsm.vlanFilterList[0]
926 oFsm.numVlanFilterEntries = 1
mpagenkodff5dda2020-08-28 11:52:01 +0000927 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300928 EntityID: vtfdID,
mpagenkodff5dda2020-08-28 11:52:01 +0000929 Attributes: me.AttributeValueMap{
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000930 "VlanFilterList": vtfdFilterList, //omci lib wants a slice for serialization
931 "ForwardOperation": uint8(0x10), //VID investigation
932 "NumberOfEntries": oFsm.numVlanFilterEntries,
mpagenkodff5dda2020-08-28 11:52:01 +0000933 },
934 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000935 logger.Debugw(ctx, "UniVlanConfigFsm sendcreate VTFD", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000936 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Girish Gowdra0b235842021-03-09 13:06:46 -0800937 meInstance := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +0000938 oFsm.pAdaptFsm.commChan, meParams)
939 //accept also nil as (error) return value for writing to LastTx
940 // - this avoids misinterpretation of new received OMCI messages
941 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
942 // send shall return (dual format) error code that can be used here for immediate error treatment
943 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +0000944 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +0000945 }
946}
947
dbainbri4d3a0dc2020-12-02 00:33:42 +0000948func (oFsm *UniVlanConfigFsm) enterConfigEvtocd(ctx context.Context, e *fsm.Event) {
949 logger.Debugw(ctx, "UniVlanConfigFsm - start config EVTOCD loop", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000950 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +0000951 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300952 go func() {
mpagenko9a304ea2020-12-16 15:54:01 +0000953 //using the first element in the slice because it's the first flow per definition here
954 errEvto := oFsm.performConfigEvtocdEntries(ctx, 0)
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300955 //This is correct passing scenario
956 if errEvto == nil {
mpagenko9a304ea2020-12-16 15:54:01 +0000957 tpID := oFsm.actualUniVlanConfigRule.TpID
958 vlanID := oFsm.actualUniVlanConfigRule.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +0000959 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
960 logger.Infow(ctx, "Setting multicast MEs, with first flow", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300961 "techProfile": tpID, "gemPort": gemPort, "vlanID": vlanID, "configuredUniFlow": oFsm.configuredUniFlow})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000962 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300963 vlanID)
964 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000965 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300966 log.Fields{"device-id": oFsm.deviceID})
967 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
968 }
969 }
970 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
971 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
972 }
973 }()
mpagenkodff5dda2020-08-28 11:52:01 +0000974}
975
dbainbri4d3a0dc2020-12-02 00:33:42 +0000976func (oFsm *UniVlanConfigFsm) enterVlanConfigDone(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000977
mpagenko9a304ea2020-12-16 15:54:01 +0000978 oFsm.mutexFlowParams.RLock()
979 defer oFsm.mutexFlowParams.RUnlock()
980
mpagenkof1fc3862021-02-16 10:09:52 +0000981 logger.Infow(ctx, "UniVlanConfigFsm config done - checking on more flows", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +0000982 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
983 "overall-uni-rules": oFsm.numUniFlows, "configured-uni-rules": oFsm.configuredUniFlow})
984 pConfigVlanStateAFsm := oFsm.pAdaptFsm
985 if pConfigVlanStateAFsm == nil {
mpagenko551a4d42020-12-08 18:09:20 +0000986 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
987 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
988 //should never happen, else: recovery would be needed from outside the FSM
989 return
990 }
991 pConfigVlanStateBaseFsm := pConfigVlanStateAFsm.pFsm
mpagenko01e726e2020-10-23 09:45:29 +0000992 if len(oFsm.uniRemoveFlowsSlice) > 0 {
993 //some further flows are to be removed, removal always starts with the first element
mpagenko9a304ea2020-12-16 15:54:01 +0000994 logger.Debugw(ctx, "UniVlanConfigFsm rule removal from ConfigDone", log.Fields{
995 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
996 "tp-id": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.TpID,
997 "set-Vlan": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.SetVid})
998 // Can't call FSM Event directly, decoupling it
mpagenko01e726e2020-10-23 09:45:29 +0000999 go func(a_pBaseFsm *fsm.FSM) {
1000 _ = a_pBaseFsm.Event(vlanEvRemFlowConfig)
1001 }(pConfigVlanStateBaseFsm)
1002 return
1003 }
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001004 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
1005 oFsm.configuredUniFlow = oFsm.numUniFlows
1006 logger.Debugw(ctx, "reconciling - skip enterVlanConfigDone processing",
1007 log.Fields{"numUniFlows": oFsm.numUniFlows, "configuredUniFlow": oFsm.configuredUniFlow, "device-id": oFsm.deviceID})
1008 return
1009 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001010 if oFsm.numUniFlows > oFsm.configuredUniFlow {
mpagenko551a4d42020-12-08 18:09:20 +00001011 if oFsm.configuredUniFlow == 0 {
mpagenko551a4d42020-12-08 18:09:20 +00001012 // this is a restart with a complete new flow, we can re-use the initial flow config control
1013 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenko9a304ea2020-12-16 15:54:01 +00001014 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001015 go func(a_pBaseFsm *fsm.FSM) {
1016 _ = a_pBaseFsm.Event(vlanEvRenew)
1017 }(pConfigVlanStateBaseFsm)
1018 return
1019 }
1020
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001021 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001022 //store the actual rule that shall be worked upon in the following transient states
1023 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +00001024 //tpId of the next rule to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001025 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko551a4d42020-12-08 18:09:20 +00001026 oFsm.TpIDWaitingFor = tpID
mpagenko551a4d42020-12-08 18:09:20 +00001027 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, tpID)
mpagenko9a304ea2020-12-16 15:54:01 +00001028 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request", log.Fields{
1029 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
1030 "set-Vlan": oFsm.actualUniVlanConfigRule.SetVid, "tp-id": tpID, "ProfDone": loTechProfDone})
1031 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001032 go func(aPBaseFsm *fsm.FSM, aTechProfDone bool) {
1033 if aTechProfDone {
1034 // let the vlan processing continue with next rule
1035 _ = aPBaseFsm.Event(vlanEvIncrFlowConfig)
1036 } else {
1037 // set to waiting for Techprofile
1038 _ = aPBaseFsm.Event(vlanEvWaitTPIncr)
1039 }
1040 }(pConfigVlanStateBaseFsm, loTechProfDone)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001041 return
1042 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001043 logger.Debugw(ctx, "UniVlanConfigFsm - VLAN config done: send dh event notification", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001044 "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001045 // it might appear that some flows are requested also after 'flowPushed' event has been generated ...
1046 // state transition notification is checked in deviceHandler
mpagenko551a4d42020-12-08 18:09:20 +00001047 // note: 'flowPushed' event is only generated if all 'pending' rules are configured
mpagenkodff5dda2020-08-28 11:52:01 +00001048 if oFsm.pDeviceHandler != nil {
mpagenkofc4f56e2020-11-04 17:17:49 +00001049 //making use of the add->remove successor enum assumption/definition
dbainbri4d3a0dc2020-12-02 00:33:42 +00001050 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(uint8(oFsm.requestEvent)+oFsm.requestEventOffset))
mpagenkodff5dda2020-08-28 11:52:01 +00001051 }
1052}
1053
dbainbri4d3a0dc2020-12-02 00:33:42 +00001054func (oFsm *UniVlanConfigFsm) enterConfigIncrFlow(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001055
1056 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
1057 logger.Debugw(ctx, "reconciling - skip further processing for incremental flow",
1058 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
1059 go func(a_pBaseFsm *fsm.FSM) {
1060 _ = a_pBaseFsm.Event(vlanEvSkipIncFlowConfig)
1061 }(oFsm.pAdaptFsm.pFsm)
1062 return
1063 }
mpagenko15ff4a52021-03-02 10:09:20 +00001064 oFsm.mutexFlowParams.Lock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001065 logger.Debugw(ctx, "UniVlanConfigFsm - start config further incremental flow", log.Fields{
Girish Gowdra041dcb32020-11-16 16:54:30 -08001066 "in state": e.FSM.Current(), "recent flow-number": oFsm.configuredUniFlow,
mpagenko01e726e2020-10-23 09:45:29 +00001067 "device-id": oFsm.deviceID})
mpagenko551a4d42020-12-08 18:09:20 +00001068 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001069
mpagenko9a304ea2020-12-16 15:54:01 +00001070 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001071 // meaning transparent setup - no specific VTFD setting required
1072 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001073 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001074 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001075 } else {
1076 if oFsm.numVlanFilterEntries == 0 {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001077 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1078 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
mpagenko9a304ea2020-12-16 15:54:01 +00001079 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + uint16(oFsm.actualUniVlanConfigRule.TpID)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001080 //no VTFD yet created
dbainbri4d3a0dc2020-12-02 00:33:42 +00001081 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001082 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001083 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001084 // 'SetVid' below is assumed to be masked already by the caller to 12 bit
mpagenko9a304ea2020-12-16 15:54:01 +00001085 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001086
mpagenko01e726e2020-10-23 09:45:29 +00001087 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001088 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1089 oFsm.numVlanFilterEntries = 1
1090 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001091 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001092 Attributes: me.AttributeValueMap{
1093 "VlanFilterList": vtfdFilterList,
1094 "ForwardOperation": uint8(0x10), //VID investigation
1095 "NumberOfEntries": oFsm.numVlanFilterEntries,
1096 },
1097 }
Girish Gowdra0b235842021-03-09 13:06:46 -08001098 meInstance := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001099 oFsm.pAdaptFsm.commChan, meParams)
1100 //accept also nil as (error) return value for writing to LastTx
1101 // - this avoids misinterpretation of new received OMCI messages
1102 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1103 // send shall return (dual format) error code that can be used here for immediate error treatment
1104 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001105 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001106 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001107 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1108 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
mpagenko551a4d42020-12-08 18:09:20 +00001109 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID +
mpagenko9a304ea2020-12-16 15:54:01 +00001110 uint16(oFsm.actualUniVlanConfigRule.TpID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001111
dbainbri4d3a0dc2020-12-02 00:33:42 +00001112 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001113 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001114 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001115 // setVid is assumed to be masked already by the caller to 12 bit
1116 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] =
mpagenko9a304ea2020-12-16 15:54:01 +00001117 uint16(oFsm.actualUniVlanConfigRule.SetVid)
mpagenko01e726e2020-10-23 09:45:29 +00001118 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001119
1120 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
1121 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
1122 // new vlan associated with a different TP.
mpagenko9a304ea2020-12-16 15:54:01 +00001123 vtfdFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001124
1125 oFsm.numVlanFilterEntries++
1126 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001127 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001128 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001129 "VlanFilterList": vtfdFilterList,
1130 "ForwardOperation": uint8(0x10), //VID investigation
1131 "NumberOfEntries": oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001132 },
1133 }
Girish Gowdra0b235842021-03-09 13:06:46 -08001134 meInstance := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001135 oFsm.pAdaptFsm.commChan, meParams)
1136 //accept also nil as (error) return value for writing to LastTx
1137 // - this avoids misinterpretation of new received OMCI messages
1138 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1139 // send shall return (dual format) error code that can be used here for immediate error treatment
1140 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001141 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001142 }
mpagenko15ff4a52021-03-02 10:09:20 +00001143 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001144 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001145 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001146 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001147 logger.Errorw(ctx, "VTFD create/set failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001148 log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001149 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001150 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001151 go func(a_pBaseFsm *fsm.FSM) {
1152 _ = a_pBaseFsm.Event(vlanEvReset)
1153 }(pConfigVlanStateBaseFsm)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001154 return
1155 }
1156 }
mpagenko15ff4a52021-03-02 10:09:20 +00001157 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001158 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
mpagenko15ff4a52021-03-02 10:09:20 +00001159 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001160 go func() {
mpagenko15ff4a52021-03-02 10:09:20 +00001161 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001162 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko15ff4a52021-03-02 10:09:20 +00001163 configuredUniFlow := oFsm.configuredUniFlow
1164 oFsm.mutexFlowParams.RUnlock()
1165 errEvto := oFsm.performConfigEvtocdEntries(ctx, configuredUniFlow)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001166 //This is correct passing scenario
1167 if errEvto == nil {
1168 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
dbainbri4d3a0dc2020-12-02 00:33:42 +00001169 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
mpagenko15ff4a52021-03-02 10:09:20 +00001170 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001171 vlanID := oFsm.actualUniVlanConfigRule.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +00001172 logger.Infow(ctx, "Setting multicast MEs for additional flows", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001173 "techProfile": tpID, "gemPort": gemPort,
1174 "vlanID": vlanID, "configuredUniFlow": oFsm.configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +00001175 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001176 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001177 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001178 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001179 log.Fields{"device-id": oFsm.deviceID})
1180 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1181 }
1182 }
1183 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
1184 }
1185 }()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001186}
1187
dbainbri4d3a0dc2020-12-02 00:33:42 +00001188func (oFsm *UniVlanConfigFsm) enterRemoveFlow(ctx context.Context, e *fsm.Event) {
mpagenko551a4d42020-12-08 18:09:20 +00001189 oFsm.mutexFlowParams.RLock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001190 logger.Debugw(ctx, "UniVlanConfigFsm - start removing the top remove-flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001191 "in state": e.FSM.Current(), "with last cookie": oFsm.uniRemoveFlowsSlice[0].cookie,
1192 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001193
mpagenkofc4f56e2020-11-04 17:17:49 +00001194 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
1195 loAllowSpecificOmciConfig := oFsm.pDeviceHandler.ReadyForSpecificOmciConfig
mpagenko01e726e2020-10-23 09:45:29 +00001196 loVlanEntryClear := uint8(0)
1197 loVlanEntryRmPos := uint8(0x80) //with indication 'invalid' in bit 7
1198 //shallow copy is sufficient as no reference variables are used within struct
1199 loRuleParams := oFsm.uniRemoveFlowsSlice[0].vlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +00001200 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001201 logger.Debugw(ctx, "UniVlanConfigFsm - remove-flow parameters are", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001202 "match vid": loRuleParams.MatchVid, "match Pcp": loRuleParams.MatchPcp,
1203 "set vid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
1204 "device-id": oFsm.deviceID})
1205
1206 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
1207 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001208 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD removal required for transparent flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001209 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1210 } else {
1211 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization and 're-copy'
1212 if oFsm.numVlanFilterEntries == 1 {
mpagenko551a4d42020-12-08 18:09:20 +00001213 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + uint16(loRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00001214 //only one active VLAN entry (hopefully the SetVID we want to remove - should be, but not verified ..)
1215 // so we can just delete the VTFD entry
dbainbri4d3a0dc2020-12-02 00:33:42 +00001216 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD delete (no more vlan filters)",
mpagenko01e726e2020-10-23 09:45:29 +00001217 log.Fields{"current vlan list": oFsm.vlanFilterList,
1218 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001219 loVlanEntryClear = 1 //full VlanFilter clear request
1220 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
Girish Gowdra0b235842021-03-09 13:06:46 -08001221 meInstance := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001222 oFsm.pAdaptFsm.commChan, vtfdID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001223 oFsm.pLastTxMeInstance = meInstance
1224 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001225 logger.Debugw(ctx, "UniVlanConfigFsm delete VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001226 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.getDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +00001227 }
mpagenko01e726e2020-10-23 09:45:29 +00001228 } else {
1229 //many VTFD already should exists - find and remove the one concerned by the actual remove rule
1230 // by updating the VTFD per set command with new valid list
dbainbri4d3a0dc2020-12-02 00:33:42 +00001231 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD removal of requested VLAN from the list on OMCI",
mpagenko01e726e2020-10-23 09:45:29 +00001232 log.Fields{"current vlan list": oFsm.vlanFilterList,
1233 "set-vlan": loRuleParams.SetVid, "device-id": oFsm.deviceID})
1234 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1235 if loRuleParams.SetVid == uint32(oFsm.vlanFilterList[i]) {
1236 loVlanEntryRmPos = i
1237 break //abort search
1238 }
1239 }
1240 if loVlanEntryRmPos < cVtfdTableSize {
mpagenko551a4d42020-12-08 18:09:20 +00001241 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + uint16(loRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00001242 //valid entry was found - to be eclipsed
1243 loVlanEntryClear = 2 //VlanFilter remove request for a specific entry
1244 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1245 if i < loVlanEntryRmPos {
1246 vtfdFilterList[i] = oFsm.vlanFilterList[i] //copy original
1247 } else if i < (cVtfdTableSize - 1) {
1248 vtfdFilterList[i] = oFsm.vlanFilterList[i+1] //copy successor (including 0 elements)
1249 } else {
1250 vtfdFilterList[i] = 0 //set last byte if needed
1251 }
1252 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001253 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001254 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001255 "new vlan list": vtfdFilterList, "device-id": oFsm.deviceID})
1256
mpagenkofc4f56e2020-11-04 17:17:49 +00001257 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001258 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
Girish Gowdra0b235842021-03-09 13:06:46 -08001259 meInstance := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001260 oFsm.pAdaptFsm.commChan, vtfdID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001261 oFsm.pLastTxMeInstance = meInstance
1262 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001263 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001264 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.getDeviceReasonString()})
mpagenko01e726e2020-10-23 09:45:29 +00001265 }
mpagenko01e726e2020-10-23 09:45:29 +00001266 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001267 logger.Warnw(ctx, "UniVlanConfigFsm: requested VLAN for removal not found in list - ignore and continue (no VTFD set)",
mpagenko01e726e2020-10-23 09:45:29 +00001268 log.Fields{"device-id": oFsm.deviceID})
1269 }
1270 }
1271 if loVlanEntryClear > 0 {
mpagenkofc4f56e2020-11-04 17:17:49 +00001272 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
1273 //waiting on response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001274 err := oFsm.waitforOmciResponse(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001275 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001276 logger.Errorw(ctx, "VTFD delete/reset failed, aborting VlanConfig FSM!",
mpagenkofc4f56e2020-11-04 17:17:49 +00001277 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001278 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001279 go func(a_pBaseFsm *fsm.FSM) {
1280 _ = a_pBaseFsm.Event(vlanEvReset)
1281 }(pConfigVlanStateBaseFsm)
1282 return
1283 }
mpagenko01e726e2020-10-23 09:45:29 +00001284 }
1285
mpagenko15ff4a52021-03-02 10:09:20 +00001286 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00001287 if loVlanEntryClear == 1 {
1288 oFsm.vlanFilterList[0] = 0 //first entry is the only that can contain the previous only-one element
1289 oFsm.numVlanFilterEntries = 0
1290 } else if loVlanEntryClear == 2 {
1291 // new VlanFilterList should be one entry smaller now - copy from last configured entry
1292 // this loop now includes the 0 element on previous last valid entry
1293 for i := uint8(0); i <= oFsm.numVlanFilterEntries; i++ {
1294 oFsm.vlanFilterList[i] = vtfdFilterList[i]
1295 }
1296 oFsm.numVlanFilterEntries--
1297 }
mpagenko15ff4a52021-03-02 10:09:20 +00001298 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001299 }
1300 }
1301
mpagenkofc4f56e2020-11-04 17:17:49 +00001302 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001303 go oFsm.removeEvtocdEntries(ctx, loRuleParams)
mpagenkofc4f56e2020-11-04 17:17:49 +00001304 } else {
1305 // OMCI processing is not done, expectation is to have the ONU in some basic config state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001306 logger.Debugw(ctx, "UniVlanConfigFsm remove EVTOCD OMCI handling skipped based on device state", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +00001307 "device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001308 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001309 go func(a_pBaseFsm *fsm.FSM) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001310 _ = a_pBaseFsm.Event(vlanEvRemFlowDone, loRuleParams.TpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001311 }(pConfigVlanStateBaseFsm)
1312 }
mpagenkodff5dda2020-08-28 11:52:01 +00001313}
1314
dbainbri4d3a0dc2020-12-02 00:33:42 +00001315func (oFsm *UniVlanConfigFsm) enterVlanCleanupDone(ctx context.Context, e *fsm.Event) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001316 var tpID uint8
1317 // Extract the tpID
1318 if len(e.Args) > 0 {
1319 tpID = e.Args[0].(uint8)
1320 logger.Debugw(ctx, "UniVlanConfigFsm - flow removed for tp id", log.Fields{"device-id": oFsm.deviceID, "tpID": e.Args[0].(uint8)})
1321 } else {
1322 logger.Warnw(ctx, "UniVlanConfigFsm - tp id not available", log.Fields{"device-id": oFsm.deviceID})
1323 }
mpagenko01e726e2020-10-23 09:45:29 +00001324 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001325 deletedCookie := oFsm.uniRemoveFlowsSlice[0].cookie
1326 logger.Debugw(ctx, "UniVlanConfigFsm - removing the removal data", log.Fields{
1327 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1328 "removed cookie": deletedCookie, "waitForDeleteCookie": oFsm.delayNewRuleCookie})
1329
mpagenko01e726e2020-10-23 09:45:29 +00001330 if len(oFsm.uniRemoveFlowsSlice) <= 1 {
1331 oFsm.uniRemoveFlowsSlice = nil //reset the slice
dbainbri4d3a0dc2020-12-02 00:33:42 +00001332 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - last remove-flow deleted", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001333 "device-id": oFsm.deviceID})
1334 } else {
1335 //cut off the actual flow by slicing out the first element
1336 oFsm.uniRemoveFlowsSlice = append(
1337 oFsm.uniRemoveFlowsSlice[:0],
1338 oFsm.uniRemoveFlowsSlice[1:]...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001339 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow deleted from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001340 "device-id": oFsm.deviceID})
1341 }
1342 oFsm.mutexFlowParams.Unlock()
1343
mpagenkof1fc3862021-02-16 10:09:52 +00001344 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
mpagenko01e726e2020-10-23 09:45:29 +00001345 //return to the basic config verification state
mpagenkodff5dda2020-08-28 11:52:01 +00001346 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1347 if pConfigVlanStateAFsm != nil {
mpagenko9a304ea2020-12-16 15:54:01 +00001348 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +00001349 go func(a_pAFsm *AdapterFsm) {
1350 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001351 _ = a_pAFsm.pFsm.Event(vlanEvFlowDataRemoved)
mpagenkodff5dda2020-08-28 11:52:01 +00001352 }
1353 }(pConfigVlanStateAFsm)
1354 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001355
1356 oFsm.mutexFlowParams.RLock()
1357 noOfFlowRem := len(oFsm.uniRemoveFlowsSlice)
mpagenkof1fc3862021-02-16 10:09:52 +00001358 if deletedCookie == oFsm.delayNewRuleCookie {
1359 // flush the channel CookieDeleted to ensure it is not lingering from some previous (aborted) activity
1360 select {
1361 case <-oFsm.chCookieDeleted:
1362 logger.Debug(ctx, "flushed CookieDeleted")
1363 default:
1364 }
1365 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue
1366 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001367 oFsm.mutexFlowParams.RUnlock()
1368 // If all pending flow removes are completed and TP ID is valid, processing any pending TP delete
1369 if noOfFlowRem == 0 && tpID > 0 {
1370 logger.Debugw(ctx, "processing pending tp delete", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID})
1371 // If we are here then all flows are removed.
1372 oFsm.pDeviceHandler.ProcessPendingTpDelete(ctx, oFsm.pOnuUniPort, tpID)
1373 }
mpagenkodff5dda2020-08-28 11:52:01 +00001374}
1375
dbainbri4d3a0dc2020-12-02 00:33:42 +00001376func (oFsm *UniVlanConfigFsm) enterResetting(ctx context.Context, e *fsm.Event) {
1377 logger.Debugw(ctx, "UniVlanConfigFsm resetting", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001378
1379 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1380 if pConfigVlanStateAFsm != nil {
1381 // abort running message processing
1382 fsmAbortMsg := Message{
1383 Type: TestMsg,
1384 Data: TestMessage{
1385 TestMessageVal: AbortMessageProcessing,
1386 },
1387 }
1388 pConfigVlanStateAFsm.commChan <- fsmAbortMsg
1389
mpagenko9a304ea2020-12-16 15:54:01 +00001390 //try to restart the FSM to 'disabled'
1391 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +00001392 go func(a_pAFsm *AdapterFsm) {
1393 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301394 _ = a_pAFsm.pFsm.Event(vlanEvRestart)
mpagenkodff5dda2020-08-28 11:52:01 +00001395 }
1396 }(pConfigVlanStateAFsm)
1397 }
1398}
1399
dbainbri4d3a0dc2020-12-02 00:33:42 +00001400func (oFsm *UniVlanConfigFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
1401 logger.Debugw(ctx, "UniVlanConfigFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001402 oFsm.pLastTxMeInstance = nil
mpagenkodff5dda2020-08-28 11:52:01 +00001403 if oFsm.pDeviceHandler != nil {
mpagenko2418ab02020-11-12 12:58:06 +00001404 //TODO: to clarify with improved error treatment for VlanConfigFsm (timeout,reception) errors
1405 // current code removes the complete FSM including all flow/rule configuration done so far
1406 // this might be a bit to much, it would require fully new flow config from rwCore (at least on OnuDown/up)
1407 // maybe a more sophisticated approach is possible without clearing the data
mpagenko9a304ea2020-12-16 15:54:01 +00001408 oFsm.mutexFlowParams.RLock()
mpagenko2418ab02020-11-12 12:58:06 +00001409 if oFsm.clearPersistency {
1410 //permanently remove possibly stored persistent data
1411 if len(oFsm.uniVlanFlowParamsSlice) > 0 {
1412 var emptySlice = make([]uniVlanFlowParams, 0)
mpagenkof1fc3862021-02-16 10:09:52 +00001413 _ = oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID, &emptySlice, true) //ignore errors
mpagenko2418ab02020-11-12 12:58:06 +00001414 }
1415 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001416 logger.Debugw(ctx, "UniVlanConfigFsm persistency data not cleared", log.Fields{"device-id": oFsm.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001417 }
mpagenkof1fc3862021-02-16 10:09:52 +00001418 if oFsm.delayNewRuleCookie != 0 {
1419 // looks like the waiting AddFlow is stuck
1420 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue/treminate
1421 }
mpagenko9a304ea2020-12-16 15:54:01 +00001422 oFsm.mutexFlowParams.RUnlock()
mpagenko2418ab02020-11-12 12:58:06 +00001423 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001424 go oFsm.pDeviceHandler.RemoveVlanFilterFsm(ctx, oFsm.pOnuUniPort)
mpagenkodff5dda2020-08-28 11:52:01 +00001425 }
1426}
1427
dbainbri4d3a0dc2020-12-02 00:33:42 +00001428func (oFsm *UniVlanConfigFsm) processOmciVlanMessages(ctx context.Context) { //ctx context.Context?
1429 logger.Debugw(ctx, "Start UniVlanConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001430loop:
1431 for {
mpagenkodff5dda2020-08-28 11:52:01 +00001432 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00001433 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001434 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +05301435 message, ok := <-oFsm.pAdaptFsm.commChan
1436 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001437 logger.Info(ctx, "UniVlanConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301438 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
1439 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1440 break loop
1441 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001442 logger.Debugw(ctx, "UniVlanConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301443
1444 switch message.Type {
1445 case TestMsg:
1446 msg, _ := message.Data.(TestMessage)
1447 if msg.TestMessageVal == AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001448 logger.Infow(ctx, "UniVlanConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001449 break loop
1450 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001451 logger.Warnw(ctx, "UniVlanConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Himani Chawla4d908332020-08-31 12:30:20 +05301452 case OMCI:
1453 msg, _ := message.Data.(OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001454 oFsm.handleOmciVlanConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301455 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001456 logger.Warn(ctx, "UniVlanConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301457 "message.Type": message.Type})
mpagenkodff5dda2020-08-28 11:52:01 +00001458 }
1459 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001460 logger.Infow(ctx, "End UniVlanConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001461}
1462
dbainbri4d3a0dc2020-12-02 00:33:42 +00001463func (oFsm *UniVlanConfigFsm) handleOmciVlanConfigMessage(ctx context.Context, msg OmciMessage) {
1464 logger.Debugw(ctx, "Rx OMCI UniVlanConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001465 "msgType": msg.OmciMsg.MessageType})
1466
1467 switch msg.OmciMsg.MessageType {
1468 case omci.CreateResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001469 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001470 if err := oFsm.handleOmciCreateResponseMessage(ctx, msg.OmciPacket); err != nil {
1471 logger.Warnw(ctx, "CreateResponse handling aborted", log.Fields{"err": err})
mpagenkodff5dda2020-08-28 11:52:01 +00001472 return
1473 }
mpagenkodff5dda2020-08-28 11:52:01 +00001474 } //CreateResponseType
1475 case omci.SetResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001476 { //leave that here as direct code as most often used
mpagenkodff5dda2020-08-28 11:52:01 +00001477 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1478 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001479 logger.Errorw(ctx, "Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001480 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001481 return
1482 }
1483 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1484 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001485 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001486 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001487 return
1488 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001489 logger.Debugw(ctx, "UniVlanConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkodff5dda2020-08-28 11:52:01 +00001490 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001491 logger.Errorw(ctx, "UniVlanConfigFsm Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001492 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
mpagenkodff5dda2020-08-28 11:52:01 +00001493 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1494 return
1495 }
mpagenko01e726e2020-10-23 09:45:29 +00001496 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1497 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1498 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001499 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "MulticastOperationsProfile":
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001500 { // let the MultiEntity config proceed by stopping the wait function
mpagenkodff5dda2020-08-28 11:52:01 +00001501 oFsm.omciMIdsResponseReceived <- true
1502 }
1503 }
1504 }
1505 } //SetResponseType
mpagenko01e726e2020-10-23 09:45:29 +00001506 case omci.DeleteResponseType:
1507 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001508 if err := oFsm.handleOmciDeleteResponseMessage(ctx, msg.OmciPacket); err != nil {
1509 logger.Warnw(ctx, "DeleteResponse handling aborted", log.Fields{"err": err})
mpagenko01e726e2020-10-23 09:45:29 +00001510 return
1511 }
1512 } //DeleteResponseType
mpagenkodff5dda2020-08-28 11:52:01 +00001513 default:
1514 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001515 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00001516 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001517 return
1518 }
1519 }
1520}
1521
dbainbri4d3a0dc2020-12-02 00:33:42 +00001522func (oFsm *UniVlanConfigFsm) handleOmciCreateResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00001523 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeCreateResponse)
1524 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001525 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001526 log.Fields{"device-id": oFsm.deviceID})
1527 return fmt.Errorf("omci msg layer could not be detected for CreateResponse for device-id %x",
1528 oFsm.deviceID)
1529 }
1530 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
1531 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001532 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001533 log.Fields{"device-id": oFsm.deviceID})
1534 return fmt.Errorf("omci msg layer could not be assigned for CreateResponse for device-id %x",
1535 oFsm.deviceID)
1536 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001537 logger.Debugw(ctx, "UniVlanConfigFsm CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001538 if msgObj.Result != me.Success && msgObj.Result != me.InstanceExists {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001539 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"device-id": oFsm.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00001540 "Error": msgObj.Result})
1541 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1542 return fmt.Errorf("omci CreateResponse Error for device-id %x",
1543 oFsm.deviceID)
1544 }
1545 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1546 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1547 // to satisfy StaticCodeAnalysis I had to move the small processing into a separate method :-(
1548 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001549 case "VlanTaggingFilterData", "MulticastOperationsProfile",
1550 "MulticastSubscriberConfigInfo", "MacBridgePortConfigurationData",
1551 "ExtendedVlanTaggingOperationConfigurationData":
mpagenko01e726e2020-10-23 09:45:29 +00001552 {
1553 if oFsm.pAdaptFsm.pFsm.Current() == vlanStConfigVtfd {
1554 // Only if CreateResponse is received from first flow entry - let the FSM proceed ...
1555 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigVtfd)
1556 } else { // let the MultiEntity config proceed by stopping the wait function
1557 oFsm.omciMIdsResponseReceived <- true
1558 }
1559 }
1560 }
1561 }
1562 return nil
1563}
1564
dbainbri4d3a0dc2020-12-02 00:33:42 +00001565func (oFsm *UniVlanConfigFsm) handleOmciDeleteResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00001566 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeDeleteResponse)
1567 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001568 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001569 log.Fields{"device-id": oFsm.deviceID})
1570 return fmt.Errorf("omci msg layer could not be detected for DeleteResponse for device-id %x",
1571 oFsm.deviceID)
1572 }
1573 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
1574 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001575 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001576 log.Fields{"device-id": oFsm.deviceID})
1577 return fmt.Errorf("omci msg layer could not be assigned for DeleteResponse for device-id %x",
1578 oFsm.deviceID)
1579 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001580 logger.Debugw(ctx, "UniVlanConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko01e726e2020-10-23 09:45:29 +00001581 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001582 logger.Errorw(ctx, "UniVlanConfigFsm - Omci DeleteResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001583 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1584 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1585 return fmt.Errorf("omci DeleteResponse Error for device-id %x",
1586 oFsm.deviceID)
1587 }
1588 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1589 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1590 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001591 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData":
mpagenko01e726e2020-10-23 09:45:29 +00001592 { // let the MultiEntity config proceed by stopping the wait function
1593 oFsm.omciMIdsResponseReceived <- true
1594 }
1595 }
1596 }
1597 return nil
1598}
1599
dbainbri4d3a0dc2020-12-02 00:33:42 +00001600func (oFsm *UniVlanConfigFsm) performConfigEvtocdEntries(ctx context.Context, aFlowEntryNo uint8) error {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001601 if aFlowEntryNo == 0 {
1602 // EthType set only at first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00001603 // EVTOCD ME is expected to exist at this point already from MIB-Download (with AssociationType/Pointer)
1604 // we need to extend the configuration by EthType definition and, to be sure, downstream 'inverse' mode
dbainbri4d3a0dc2020-12-02 00:33:42 +00001605 logger.Debugw(ctx, "UniVlanConfigFsm Tx Create::EVTOCD", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00001606 "EntitytId": strconv.FormatInt(int64(oFsm.evtocdID), 16),
1607 "i/oEthType": strconv.FormatInt(int64(cDefaultTpid), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001608 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001609 associationType := 2 // default to uniPPTP
1610 if oFsm.pOnuUniPort.portType == uniVEIP {
1611 associationType = 10
1612 }
1613 // Create the EVTOCD ME
mpagenkodff5dda2020-08-28 11:52:01 +00001614 meParams := me.ParamData{
1615 EntityID: oFsm.evtocdID,
1616 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001617 "AssociationType": uint8(associationType),
1618 "AssociatedMePointer": oFsm.pOnuUniPort.entityID,
mpagenkodff5dda2020-08-28 11:52:01 +00001619 },
1620 }
Girish Gowdra0b235842021-03-09 13:06:46 -08001621 meInstance := oFsm.pOmciCC.sendCreateEvtocdVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001622 oFsm.pAdaptFsm.commChan, meParams)
1623 //accept also nil as (error) return value for writing to LastTx
1624 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001625 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001626
1627 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001628 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001629 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001630 logger.Errorw(ctx, "Evtocd create failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001631 log.Fields{"device-id": oFsm.deviceID})
1632 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1633 return fmt.Errorf("evtocd create failed %s, error %s", oFsm.deviceID, err)
1634 }
1635
1636 // Set the EVTOCD ME default params
1637 meParams = me.ParamData{
1638 EntityID: oFsm.evtocdID,
1639 Attributes: me.AttributeValueMap{
1640 "InputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
1641 "OutputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
1642 "DownstreamMode": uint8(cDefaultDownstreamMode),
1643 },
1644 }
Girish Gowdra0b235842021-03-09 13:06:46 -08001645 meInstance = oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001646 oFsm.pAdaptFsm.commChan, meParams)
1647 //accept also nil as (error) return value for writing to LastTx
1648 // - this avoids misinterpretation of new received OMCI messages
1649 oFsm.pLastTxMeInstance = meInstance
1650
1651 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001652 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001653 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001654 logger.Errorw(ctx, "Evtocd set TPID failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001655 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301656 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001657 return fmt.Errorf("evtocd set TPID failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00001658 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001659 } //first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00001660
mpagenko551a4d42020-12-08 18:09:20 +00001661 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001662 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00001663 //transparent transmission required
mpagenko551a4d42020-12-08 18:09:20 +00001664 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001665 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged transparent rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001666 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001667 sliceEvtocdRule := make([]uint8, 16)
1668 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1669 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1670 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1671 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1672 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1673
1674 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1675 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
1676 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1677 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1678 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1679
1680 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1681 0<<cTreatTTROffset| // Do not pop any tags
1682 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1683 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1684 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1685
1686 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1687 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
1688 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1689 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
1690
1691 meParams := me.ParamData{
1692 EntityID: oFsm.evtocdID,
1693 Attributes: me.AttributeValueMap{
1694 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1695 },
1696 }
Girish Gowdra0b235842021-03-09 13:06:46 -08001697 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001698 oFsm.pAdaptFsm.commChan, meParams)
1699 //accept also nil as (error) return value for writing to LastTx
1700 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001701 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001702
1703 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001704 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001705 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001706 logger.Errorw(ctx, "Evtocd set transparent singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001707 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301708 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001709 return fmt.Errorf("evtocd set transparent singletagged rule failed %s, error %s", oFsm.deviceID, err)
1710
mpagenkodff5dda2020-08-28 11:52:01 +00001711 }
1712 } else {
1713 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
1714 if oFsm.acceptIncrementalEvtoOption {
mpagenko9a304ea2020-12-16 15:54:01 +00001715 matchPcp := oFsm.actualUniVlanConfigRule.MatchPcp
1716 matchVid := oFsm.actualUniVlanConfigRule.MatchVid
1717 setPcp := oFsm.actualUniVlanConfigRule.SetPcp
1718 setVid := oFsm.actualUniVlanConfigRule.SetVid
mpagenkodff5dda2020-08-28 11:52:01 +00001719 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001720 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged translation rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001721 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001722 sliceEvtocdRule := make([]uint8, 16)
1723 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1724 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1725 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1726 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1727 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1728
1729 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00001730 oFsm.actualUniVlanConfigRule.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
1731 oFsm.actualUniVlanConfigRule.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
mpagenkodff5dda2020-08-28 11:52:01 +00001732 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1733 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1734
1735 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00001736 oFsm.actualUniVlanConfigRule.TagsToRemove<<cTreatTTROffset| // either 1 or 0
mpagenkodff5dda2020-08-28 11:52:01 +00001737 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1738 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1739 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1740
1741 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00001742 oFsm.actualUniVlanConfigRule.SetPcp<<cTreatPrioOffset| // as configured in flow
1743 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| //as configured in flow
mpagenkodff5dda2020-08-28 11:52:01 +00001744 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00001745 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001746
1747 meParams := me.ParamData{
1748 EntityID: oFsm.evtocdID,
1749 Attributes: me.AttributeValueMap{
1750 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1751 },
1752 }
Girish Gowdra0b235842021-03-09 13:06:46 -08001753 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001754 oFsm.pAdaptFsm.commChan, meParams)
1755 //accept also nil as (error) return value for writing to LastTx
1756 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001757 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001758
1759 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001760 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001761 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001762 logger.Errorw(ctx, "Evtocd set singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001763 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301764 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001765 return fmt.Errorf("evtocd set singletagged translation rule failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00001766 }
1767 } else {
1768 //not transparent and not acceptIncrementalEvtoOption untagged/priotagged->singletagged
1769 { // just for local var's
1770 // this defines stacking scenario: untagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00001771 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD untagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001772 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001773 sliceEvtocdRule := make([]uint8, 16)
1774 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1775 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1776 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1777 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1778 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1779
1780 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1781 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
1782 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1783 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1784 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1785
1786 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1787 0<<cTreatTTROffset| // Do not pop any tags
1788 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1789 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1790 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1791
1792 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1793 0<<cTreatPrioOffset| // vlan prio set to 0
1794 // (as done in Py code, maybe better option would be setPcp here, which still could be 0?)
mpagenko9a304ea2020-12-16 15:54:01 +00001795 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| // Outer VID don't care
mpagenkodff5dda2020-08-28 11:52:01 +00001796 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
1797
mpagenko551a4d42020-12-08 18:09:20 +00001798 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001799 meParams := me.ParamData{
1800 EntityID: oFsm.evtocdID,
1801 Attributes: me.AttributeValueMap{
1802 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1803 },
1804 }
Girish Gowdra0b235842021-03-09 13:06:46 -08001805 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001806 oFsm.pAdaptFsm.commChan, meParams)
1807 //accept also nil as (error) return value for writing to LastTx
1808 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001809 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001810
1811 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001812 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001813 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001814 logger.Errorw(ctx, "Evtocd set untagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001815 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301816 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001817 return fmt.Errorf("evtocd set untagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
1818
mpagenkodff5dda2020-08-28 11:52:01 +00001819 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001820 } // just for local var's
mpagenkodff5dda2020-08-28 11:52:01 +00001821 { // just for local var's
1822 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00001823 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD priotagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001824 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001825 sliceEvtocdRule := make([]uint8, 16)
1826 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1827 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1828 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1829 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1830 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1831
1832 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1833 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
1834 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
1835 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1836 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1837
1838 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1839 1<<cTreatTTROffset| // pop the prio-tag
1840 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1841 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1842 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1843
mpagenko551a4d42020-12-08 18:09:20 +00001844 oFsm.mutexFlowParams.RLock()
mpagenkodff5dda2020-08-28 11:52:01 +00001845 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1846 cCopyPrioFromInner<<cTreatPrioOffset| // vlan copy from PrioTag
1847 // (as done in Py code, maybe better option would be setPcp here, which still could be PrioCopy?)
mpagenko9a304ea2020-12-16 15:54:01 +00001848 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| // Outer VID as configured
mpagenkodff5dda2020-08-28 11:52:01 +00001849 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00001850 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001851
1852 meParams := me.ParamData{
1853 EntityID: oFsm.evtocdID,
1854 Attributes: me.AttributeValueMap{
1855 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1856 },
1857 }
Girish Gowdra0b235842021-03-09 13:06:46 -08001858 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001859 oFsm.pAdaptFsm.commChan, meParams)
1860 //accept also nil as (error) return value for writing to LastTx
1861 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001862 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001863
1864 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001865 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001866 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001867 logger.Errorw(ctx, "Evtocd set priotagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001868 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301869 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001870 return fmt.Errorf("evtocd set priotagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
1871
mpagenkodff5dda2020-08-28 11:52:01 +00001872 }
1873 } //just for local var's
1874 }
1875 }
1876
mpagenkofc4f56e2020-11-04 17:17:49 +00001877 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001878 logger.Debugw(ctx, "EVTOCD set loop finished", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001879 oFsm.configuredUniFlow++ // one (more) flow configured
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001880 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00001881}
1882
dbainbri4d3a0dc2020-12-02 00:33:42 +00001883func (oFsm *UniVlanConfigFsm) removeEvtocdEntries(ctx context.Context, aRuleParams uniVlanRuleParams) {
mpagenko01e726e2020-10-23 09:45:29 +00001884 // configured Input/Output TPID is not modified again - no influence if no filter is applied
1885 if aRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
1886 //transparent transmission was set
1887 //perhaps the config is not needed for removal,
1888 // but the specific InnerTpid setting is removed in favor of the real default forwarding rule
dbainbri4d3a0dc2020-12-02 00:33:42 +00001889 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset to default single tagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001890 "device-id": oFsm.deviceID})
1891 sliceEvtocdRule := make([]uint8, 16)
1892 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1893 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1894 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1895 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1896 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1897
1898 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1899 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
1900 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1901 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1902 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1903
1904 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1905 0<<cTreatTTROffset| // Do not pop any tags
1906 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1907 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1908 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1909
1910 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1911 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
1912 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1913 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
1914
1915 meParams := me.ParamData{
1916 EntityID: oFsm.evtocdID,
1917 Attributes: me.AttributeValueMap{
1918 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1919 },
1920 }
Girish Gowdra0b235842021-03-09 13:06:46 -08001921 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00001922 oFsm.pAdaptFsm.commChan, meParams)
1923 //accept also nil as (error) return value for writing to LastTx
1924 // - this avoids misinterpretation of new received OMCI messages
1925 oFsm.pLastTxMeInstance = meInstance
1926
1927 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001928 err := oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001929 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001930 logger.Errorw(ctx, "Evtocd reset singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001931 log.Fields{"device-id": oFsm.deviceID})
1932 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1933 return
1934 }
1935 } else {
1936 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
1937 if oFsm.acceptIncrementalEvtoOption {
1938 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001939 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear single tagged translation rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001940 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
1941 sliceEvtocdRule := make([]uint8, 16)
1942 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1943 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1944 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1945 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1946 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1947
1948 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1949 aRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
1950 aRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
1951 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1952 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1953
1954 // delete indication for the indicated Filter
1955 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
1956 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
1957
1958 meParams := me.ParamData{
1959 EntityID: oFsm.evtocdID,
1960 Attributes: me.AttributeValueMap{
1961 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1962 },
1963 }
Girish Gowdra0b235842021-03-09 13:06:46 -08001964 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00001965 oFsm.pAdaptFsm.commChan, meParams)
1966 //accept also nil as (error) return value for writing to LastTx
1967 // - this avoids misinterpretation of new received OMCI messages
1968 oFsm.pLastTxMeInstance = meInstance
1969
1970 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001971 err := oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001972 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001973 logger.Errorw(ctx, "Evtocd clear singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001974 log.Fields{"device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
1975 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1976 return
1977 }
1978 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001979 // VOL-3685
1980 // NOTE: With ALPHA ONUs it was seen that just resetting a particular entry in the EVTOCD table
1981 // and re-configuring a new entry would not work. The old entry is removed and new entry is created
1982 // indeed, but the traffic landing upstream would carry old vlan sometimes.
1983 // This is only a WORKAROUND which basically deletes the entire EVTOCD ME and re-creates it again
1984 // later when the flow is being re-installed.
1985 // Of course this is applicable to case only where single service (or single tcont) is in use and
1986 // there is only one service vlan (oFsm.acceptIncrementalEvtoOption is false in this case).
1987 // Interstingly this problem has not been observed in multi-tcont (or multi-service) scenario (in
1988 // which case the oFsm.acceptIncrementalEvtoOption is set to true).
1989 if oFsm.configuredUniFlow == 0 && !oFsm.acceptIncrementalEvtoOption {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001990 logger.Debugw(ctx, "UniVlanConfigFsm Tx Remove::EVTOCD", log.Fields{"device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001991 // When there are no more EVTOCD vlan configurations on the ONU and acceptIncrementalEvtoOption
1992 // is not enabled, delete the EVTOCD ME.
mpagenko01e726e2020-10-23 09:45:29 +00001993 meParams := me.ParamData{
1994 EntityID: oFsm.evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00001995 }
Girish Gowdra0b235842021-03-09 13:06:46 -08001996 meInstance := oFsm.pOmciCC.sendDeleteEvtocd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00001997 oFsm.pAdaptFsm.commChan, meParams)
1998 //accept also nil as (error) return value for writing to LastTx
1999 // - this avoids misinterpretation of new received OMCI messages
2000 oFsm.pLastTxMeInstance = meInstance
2001
2002 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002003 err := oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002004 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002005 logger.Errorw(ctx, "Evtocd delete rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002006 log.Fields{"device-id": oFsm.deviceID})
2007 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2008 return
2009 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002010 } else {
2011 // NOTE : We should ideally never ether this section when oFsm.acceptIncrementalEvtoOption is set to false
2012 // This is true for only ATT/DT workflow
dbainbri4d3a0dc2020-12-02 00:33:42 +00002013 logger.Debugw(ctx, "UniVlanConfigFsm: Remove EVTOCD set operation",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002014 log.Fields{"configured-flow": oFsm.configuredUniFlow, "incremental-evto": oFsm.acceptIncrementalEvtoOption})
2015 //not transparent and not acceptIncrementalEvtoOption: untagged/priotagged->singletagged
2016 { // just for local var's
2017 // this defines stacking scenario: untagged->singletagged
2018 //TODO!! in theory there could be different rules running in setting different PCP/VID'S
2019 // for untagged/priotagged, last rule wins (and remains the only one), maybe that should be
2020 // checked already at flow-add (and rejected) - to be observed if such is possible in Voltha
2021 // delete now assumes there is only one such rule!
dbainbri4d3a0dc2020-12-02 00:33:42 +00002022 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset untagged rule to default", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002023 "device-id": oFsm.deviceID})
2024 sliceEvtocdRule := make([]uint8, 16)
2025 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2026 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2027 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2028 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2029 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00002030
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002031 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2032 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2033 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2034 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2035 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00002036
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002037 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2038 0<<cTreatTTROffset| // Do not pop any tags
2039 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2040 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2041 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
mpagenko01e726e2020-10-23 09:45:29 +00002042
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002043 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2044 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2045 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2046 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
mpagenko01e726e2020-10-23 09:45:29 +00002047
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002048 meParams := me.ParamData{
2049 EntityID: oFsm.evtocdID,
2050 Attributes: me.AttributeValueMap{
2051 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2052 },
2053 }
Girish Gowdra0b235842021-03-09 13:06:46 -08002054 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002055 oFsm.pAdaptFsm.commChan, meParams)
2056 //accept also nil as (error) return value for writing to LastTx
2057 // - this avoids misinterpretation of new received OMCI messages
2058 oFsm.pLastTxMeInstance = meInstance
2059
2060 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002061 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002062 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002063 logger.Errorw(ctx, "Evtocd reset untagged rule to default failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002064 log.Fields{"device-id": oFsm.deviceID})
2065 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2066 return
2067 }
2068 } // just for local var's
2069 { // just for local var's
2070 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002071 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD delete priotagged rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002072 "device-id": oFsm.deviceID})
2073 sliceEvtocdRule := make([]uint8, 16)
2074 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2075 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2076 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2077 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2078 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2079
2080 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2081 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2082 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2083 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2084 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2085
2086 // delete indication for the indicated Filter
2087 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2088 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2089
2090 meParams := me.ParamData{
2091 EntityID: oFsm.evtocdID,
2092 Attributes: me.AttributeValueMap{
2093 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2094 },
2095 }
Girish Gowdra0b235842021-03-09 13:06:46 -08002096 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002097 oFsm.pAdaptFsm.commChan, meParams)
2098 //accept also nil as (error) return value for writing to LastTx
2099 // - this avoids misinterpretation of new received OMCI messages
2100 oFsm.pLastTxMeInstance = meInstance
2101
2102 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002103 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002104 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002105 logger.Errorw(ctx, "Evtocd delete priotagged rule failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002106 log.Fields{"device-id": oFsm.deviceID})
2107 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2108 return
2109 }
mpagenko01e726e2020-10-23 09:45:29 +00002110 }
2111 } //just for local var's
2112 }
2113 }
2114
mpagenkofc4f56e2020-11-04 17:17:49 +00002115 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002116 logger.Debugw(ctx, "EVTOCD filter remove loop finished", log.Fields{"device-id": oFsm.deviceID})
Girish Gowdra26a40922021-01-29 17:14:34 -08002117 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRemFlowDone, aRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00002118}
2119
dbainbri4d3a0dc2020-12-02 00:33:42 +00002120func (oFsm *UniVlanConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00002121 oFsm.mutexIsAwaitingResponse.Lock()
2122 oFsm.isAwaitingResponse = true
2123 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002124 select {
Himani Chawla26e555c2020-08-31 12:30:20 +05302125 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenkodff5dda2020-08-28 11:52:01 +00002126 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00002127 // logger.Infow(ctx,"LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002128 case <-time.After(30 * time.Second): //AS FOR THE OTHER OMCI FSM's
dbainbri4d3a0dc2020-12-02 00:33:42 +00002129 logger.Warnw(ctx, "UniVlanConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002130 oFsm.mutexIsAwaitingResponse.Lock()
2131 oFsm.isAwaitingResponse = false
2132 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002133 return fmt.Errorf("uniVlanConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002134 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05302135 if success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002136 logger.Debug(ctx, "UniVlanConfigFsm multi entity response received")
mpagenko7d6bb022021-03-11 15:07:55 +00002137 oFsm.mutexIsAwaitingResponse.Lock()
2138 oFsm.isAwaitingResponse = false
2139 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002140 return nil
2141 }
mpagenko7d6bb022021-03-11 15:07:55 +00002142 // waiting was aborted (probably on external request)
2143 logger.Debugw(ctx, "UniVlanConfigFsm wait for multi entity response aborted", log.Fields{"for device-id": oFsm.deviceID})
2144 oFsm.mutexIsAwaitingResponse.Lock()
2145 oFsm.isAwaitingResponse = false
2146 oFsm.mutexIsAwaitingResponse.Unlock()
2147 return fmt.Errorf(cErrWaitAborted)
mpagenkodff5dda2020-08-28 11:52:01 +00002148 }
2149}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002150
mpagenko551a4d42020-12-08 18:09:20 +00002151func (oFsm *UniVlanConfigFsm) performSettingMulticastME(ctx context.Context, tpID uint8, multicastGemPortID uint16, vlanID uint32) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002152 logger.Debugw(ctx, "Setting Multicast MEs", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002153 "multicastGemPortID": multicastGemPortID, "vlanID": vlanID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002154 errCreateMOP := oFsm.performCreatingMulticastOperationProfile(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002155 if errCreateMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002156 logger.Errorw(ctx, "MulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002157 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002158 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002159 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMOP)
2160 }
2161
dbainbri4d3a0dc2020-12-02 00:33:42 +00002162 errSettingMOP := oFsm.performSettingMulticastOperationProfile(ctx, multicastGemPortID, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002163 if errSettingMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002164 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002165 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002166 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002167 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errSettingMOP)
2168 }
2169
dbainbri4d3a0dc2020-12-02 00:33:42 +00002170 errCreateMSCI := oFsm.performCreatingMulticastSubscriberConfigInfo(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002171 if errCreateMSCI != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002172 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002173 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002174 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002175 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMSCI)
2176 }
2177
2178 meParams := me.ParamData{
2179 EntityID: macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo),
2180 Attributes: me.AttributeValueMap{
2181 "BridgeIdPointer": macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo),
2182 "PortNum": 0xf0, //fixed unique ANI side indication
2183 "TpType": 6, //MCGemIWTP
2184 "TpPointer": multicastGemPortID,
2185 },
2186 }
Girish Gowdra0b235842021-03-09 13:06:46 -08002187 meInstance := oFsm.pOmciCC.sendCreateMBPConfigDataVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002188 oFsm.pAdaptFsm.commChan, meParams)
2189 //accept also nil as (error) return value for writing to LastTx
2190 // - this avoids misinterpretation of new received OMCI messages
2191 oFsm.pLastTxMeInstance = meInstance
dbainbri4d3a0dc2020-12-02 00:33:42 +00002192 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002193 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002194 logger.Errorw(ctx, "CreateMBPConfigData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002195 log.Fields{"device-id": oFsm.deviceID, "MBPConfigDataID": macBridgeServiceProfileEID})
mpagenko9a304ea2020-12-16 15:54:01 +00002196 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002197 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, err)
2198 }
2199
2200 // ==> Start creating VTFD for mcast vlan
2201
2202 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
2203 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
2204 mcastVtfdID := macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo)
2205
dbainbri4d3a0dc2020-12-02 00:33:42 +00002206 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD for mcast", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002207 "EntitytId": strconv.FormatInt(int64(mcastVtfdID), 16), "mcastVlanID": vlanID,
2208 "in state": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
2209 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
2210
2211 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
2212 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
2213 // new vlan associated with a different TP.
2214 vtfdFilterList[0] = uint16(vlanID)
2215
2216 meParams = me.ParamData{
2217 EntityID: mcastVtfdID,
2218 Attributes: me.AttributeValueMap{
2219 "VlanFilterList": vtfdFilterList,
2220 "ForwardOperation": uint8(0x10), //VID investigation
2221 "NumberOfEntries": oFsm.numVlanFilterEntries,
2222 },
2223 }
Girish Gowdra0b235842021-03-09 13:06:46 -08002224 meInstance = oFsm.pOmciCC.sendCreateVtfdVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002225 oFsm.pAdaptFsm.commChan, meParams)
2226 oFsm.pLastTxMeInstance = meInstance
dbainbri4d3a0dc2020-12-02 00:33:42 +00002227 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002228 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002229 logger.Errorw(ctx, "CreateMcastVlanFilterData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002230 log.Fields{"device-id": oFsm.deviceID, "mcastVtfdID": mcastVtfdID})
mpagenko9a304ea2020-12-16 15:54:01 +00002231 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002232 return fmt.Errorf("createMcastVlanFilterData responseError %s, error %s", oFsm.deviceID, err)
2233 }
2234
2235 return nil
2236}
2237
dbainbri4d3a0dc2020-12-02 00:33:42 +00002238func (oFsm *UniVlanConfigFsm) performCreatingMulticastSubscriberConfigInfo(ctx context.Context) error {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002239 instID, err := oFsm.pDeviceHandler.getUniPortMEEntityID(oFsm.pOnuUniPort.portNo)
2240 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002241 logger.Errorw(ctx, "error fetching uni port me instance",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002242 log.Fields{"device-id": oFsm.deviceID, "portNo": oFsm.pOnuUniPort.portNo})
2243 return err
2244 }
ozgecanetsia5c88b762021-03-23 10:27:15 +03002245 instID += macBridgePortAniEID
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002246 meParams := me.ParamData{
2247 EntityID: instID,
2248 Attributes: me.AttributeValueMap{
2249 "MeType": 0,
2250 //Direct reference to the Operation profile
2251 //TODO ANI side used on UNI side, not the clearest option.
ozgecanetsia5c88b762021-03-23 10:27:15 +03002252 "MulticastOperationsProfilePointer": instID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002253 },
2254 }
Girish Gowdra0b235842021-03-09 13:06:46 -08002255 meInstance := oFsm.pOmciCC.sendCreateMulticastSubConfigInfoVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002256 oFsm.pAdaptFsm.commChan, meParams)
2257 //accept also nil as (error) return value for writing to LastTx
2258 // - this avoids misinterpretation of new received OMCI messages
2259 oFsm.pLastTxMeInstance = meInstance
2260 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002261 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002262 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002263 logger.Errorw(ctx, "CreateMulticastSubConfigInfo create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002264 log.Fields{"device-id": oFsm.deviceID, "MulticastSubConfigInfo": instID})
2265 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s", oFsm.deviceID)
2266 }
2267 return nil
2268}
2269
dbainbri4d3a0dc2020-12-02 00:33:42 +00002270func (oFsm *UniVlanConfigFsm) performCreatingMulticastOperationProfile(ctx context.Context) error {
ozgecanetsia5c88b762021-03-23 10:27:15 +03002271 instID, err := oFsm.pDeviceHandler.getUniPortMEEntityID(oFsm.pOnuUniPort.portNo)
2272 if err != nil {
2273 logger.Errorw(ctx, "error fetching uni port me instance",
2274 log.Fields{"device-id": oFsm.deviceID, "portNo": oFsm.pOnuUniPort.portNo})
2275 return err
2276 }
2277 instID += macBridgePortAniEID
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002278 meParams := me.ParamData{
2279 EntityID: instID,
2280 Attributes: me.AttributeValueMap{
2281 "IgmpVersion": 2,
2282 "IgmpFunction": 0,
2283 //0 means false
2284 "ImmediateLeave": 0,
2285 "Robustness": 2,
2286 "QuerierIp": 0,
2287 "QueryInterval": 125,
2288 "QuerierMaxResponseTime": 100,
2289 "LastMemberResponseTime": 10,
2290 //0 means false
2291 "UnauthorizedJoinBehaviour": 0,
2292 },
2293 }
Girish Gowdra0b235842021-03-09 13:06:46 -08002294 meInstance := oFsm.pOmciCC.sendCreateMulticastOperationProfileVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002295 oFsm.pAdaptFsm.commChan, meParams)
2296 //accept also nil as (error) return value for writing to LastTx
2297 // - this avoids misinterpretation of new received OMCI messages
2298 oFsm.pLastTxMeInstance = meInstance
2299 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03002300 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002301 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002302 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002303 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
2304 return fmt.Errorf("createMulticastOperationProfile responseError %s", oFsm.deviceID)
2305 }
2306 return nil
2307}
2308
dbainbri4d3a0dc2020-12-02 00:33:42 +00002309func (oFsm *UniVlanConfigFsm) performSettingMulticastOperationProfile(ctx context.Context, multicastGemPortID uint16, vlanID uint32) error {
ozgecanetsia5c88b762021-03-23 10:27:15 +03002310 instID, err := oFsm.pDeviceHandler.getUniPortMEEntityID(oFsm.pOnuUniPort.portNo)
2311 if err != nil {
2312 logger.Errorw(ctx, "error fetching uni port me instance",
2313 log.Fields{"device-id": oFsm.deviceID, "portNo": oFsm.pOnuUniPort.portNo})
2314 return err
2315 }
2316 instID += macBridgePortAniEID
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002317 //TODO check that this is correct
2318 // Table control
2319 //setCtrl = 1
2320 //rowPartId = 0
2321 //test = 0
2322 //rowKey = 0
2323 tableCtrlStr := "0100000000000000"
2324 tableCtrl := AsByteSlice(tableCtrlStr)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002325 dynamicAccessCL := make([]uint8, 24)
2326 copy(dynamicAccessCL, tableCtrl)
2327 //Multicast GemPortId
2328 binary.BigEndian.PutUint16(dynamicAccessCL[2:], multicastGemPortID)
2329 // python version waits for installation of flows, see line 723 onward of
2330 // brcm_openomci_onu_handler.py
2331 binary.BigEndian.PutUint16(dynamicAccessCL[4:], uint16(vlanID))
2332 //Source IP all to 0
2333 binary.BigEndian.PutUint32(dynamicAccessCL[6:], IPToInt32(net.IPv4(0, 0, 0, 0)))
2334 //TODO start and end are hardcoded, get from TP
2335 // Destination IP address start of range
2336 binary.BigEndian.PutUint32(dynamicAccessCL[10:], IPToInt32(net.IPv4(225, 0, 0, 0)))
2337 // Destination IP address end of range
2338 binary.BigEndian.PutUint32(dynamicAccessCL[14:], IPToInt32(net.IPv4(239, 255, 255, 255)))
2339 //imputed group bandwidth
2340 binary.BigEndian.PutUint16(dynamicAccessCL[18:], 0)
2341
2342 meParams := me.ParamData{
2343 EntityID: instID,
2344 Attributes: me.AttributeValueMap{
2345 "DynamicAccessControlListTable": dynamicAccessCL,
2346 },
2347 }
Girish Gowdra0b235842021-03-09 13:06:46 -08002348 meInstance := oFsm.pOmciCC.sendSetMulticastOperationProfileVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002349 oFsm.pAdaptFsm.commChan, meParams)
2350 //accept also nil as (error) return value for writing to LastTx
2351 // - this avoids misinterpretation of new received OMCI messages
2352 oFsm.pLastTxMeInstance = meInstance
2353 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03002354 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002355 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002356 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002357 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
2358 return fmt.Errorf("createMulticastOperationProfile responseError %s", oFsm.deviceID)
2359 }
2360 return nil
2361}
Girish Gowdra26a40922021-01-29 17:14:34 -08002362
2363// IsFlowRemovePending returns true if there are pending flows to remove, else false.
2364func (oFsm *UniVlanConfigFsm) IsFlowRemovePending() bool {
2365 oFsm.mutexFlowParams.RLock()
2366 defer oFsm.mutexFlowParams.RUnlock()
2367 return len(oFsm.uniRemoveFlowsSlice) > 0
2368}