blob: 45e09448bf7112cfd1c5e8b1d5c5136b3945e6f4 [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
mpagenko73143992021-04-09 15:17:10 +0000333func (oFsm *UniVlanConfigFsm) CancelProcessing(ctx context.Context) {
mpagenko7d6bb022021-03-11 15:07:55 +0000334 //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 {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000344 if pAdaptFsm.pFsm != nil {
345 _ = pAdaptFsm.pFsm.Event(vlanEvReset)
346 }
mpagenko7d6bb022021-03-11 15:07:55 +0000347 }
348}
349
mpagenko551a4d42020-12-08 18:09:20 +0000350//GetWaitingTpID returns the TpId that the FSM might be waiting for continuation (0 if none)
351func (oFsm *UniVlanConfigFsm) GetWaitingTpID() uint8 {
352 //mutex protection is required for possible concurrent access to FSM members
353 oFsm.mutexFlowParams.RLock()
354 defer oFsm.mutexFlowParams.RUnlock()
355 return oFsm.TpIDWaitingFor
356}
357
mpagenko2418ab02020-11-12 12:58:06 +0000358//RequestClearPersistency sets the internal flag to not clear persistency data (false=NoClear)
359func (oFsm *UniVlanConfigFsm) RequestClearPersistency(aClear bool) {
360 //mutex protection is required for possible concurrent access to FSM members
mpagenko15ff4a52021-03-02 10:09:20 +0000361 oFsm.mutexFlowParams.Lock()
362 defer oFsm.mutexFlowParams.Unlock()
mpagenko2418ab02020-11-12 12:58:06 +0000363 oFsm.clearPersistency = aClear
364}
365
mpagenko01e726e2020-10-23 09:45:29 +0000366//SetUniFlowParams verifies on existence of flow parameters to be configured,
367// optionally udates the cookie list or appends a new flow if there is space
368// if possible the FSM is trigggerd to start with the processing
mpagenko551a4d42020-12-08 18:09:20 +0000369// ignore complexity by now
370// nolint: gocyclo
371func (oFsm *UniVlanConfigFsm) SetUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +0000372 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) error {
373 loRuleParams := uniVlanRuleParams{
374 TpID: aTpID,
375 MatchVid: uint32(aMatchVlan),
376 SetVid: uint32(aSetVlan),
377 SetPcp: uint32(aSetPcp),
378 }
379 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
380 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
381 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
382
383 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
384 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
385 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
386 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
387 } else {
388 if !oFsm.acceptIncrementalEvtoOption {
389 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
390 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
391 }
392 }
393
394 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
395 // no prio/vid filtering requested
396 loRuleParams.TagsToRemove = 0 //no tag pop action
397 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
398 if loRuleParams.SetPcp == cCopyPrioFromInner {
399 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
400 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
401 // might collide with NoMatchVid/CopyPrio(/setVid) setting
402 // this was some precondition setting taken over from py adapter ..
403 loRuleParams.SetPcp = 0
404 }
405 }
406
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000407 flowEntryMatch := false
mpagenko01e726e2020-10-23 09:45:29 +0000408 flowCookieModify := false
mpagenkof1fc3862021-02-16 10:09:52 +0000409 requestAppendRule := false
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000410 //mutex protection is required for possible concurrent access to FSM members
411 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +0000412 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
413 //TODO: Verify if using e.g. hashes for the structures here for comparison may generate
414 // countable run time optimization (perhaps with including the hash in kvStore storage?)
415 if storedUniFlowParams.VlanRuleParams == loRuleParams {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000416 flowEntryMatch = true
dbainbri4d3a0dc2020-12-02 00:33:42 +0000417 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - rule already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000418 "device-id": oFsm.deviceID})
419 var cookieMatch bool
420 for _, newCookie := range aCookieSlice { // for all cookies available in the arguments
421 cookieMatch = false
422 for _, cookie := range storedUniFlowParams.CookieSlice {
423 if cookie == newCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000424 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - and cookie already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000425 "device-id": oFsm.deviceID, "cookie": cookie})
426 cookieMatch = true
427 break //found new cookie - no further search for this requested cookie
428 }
429 }
430 if !cookieMatch {
mpagenkof1fc3862021-02-16 10:09:52 +0000431 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
432 if delayedCookie != 0 {
433 //a delay for adding the cookie to this rule is requested
434 // take care of the mutex which is already locked here, need to unlock/lock accordingly to prevent deadlock in suspension
435 oFsm.mutexFlowParams.Unlock()
436 oFsm.suspendNewRule(ctx)
437 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
438 oFsm.mutexFlowParams.Lock()
439 } else {
440 logger.Debugw(ctx, "UniVlanConfigFsm flow setting -adding new cookie", log.Fields{
441 "device-id": oFsm.deviceID, "cookie": newCookie})
442 //as range works with copies of the slice we have to write to the original slice!!
443 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
444 newCookie)
445 flowCookieModify = true
446 }
mpagenko01e726e2020-10-23 09:45:29 +0000447 }
448 } //for all new cookies
449 break // found rule - no further rule search
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000450 }
451 }
mpagenkof1fc3862021-02-16 10:09:52 +0000452 oFsm.mutexFlowParams.Unlock()
453
454 if !flowEntryMatch { //it is (was) a new rule
455 delayedCookie := oFsm.suspendIfRequiredNewRule(ctx, aCookieSlice)
456 requestAppendRule = true //default assumption here is that rule is to be appended
457 flowCookieModify = true //and that the the flow data base is to be updated
458 if delayedCookie != 0 { //it was suspended
459 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
460 }
461 }
462 kvStoreWrite := false //default setting is to not write to kvStore immediately - will be done on FSM execution finally
463 if requestAppendRule {
464 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000465 if oFsm.numUniFlows < cMaxAllowedFlows {
mpagenko01e726e2020-10-23 09:45:29 +0000466 loFlowParams := uniVlanFlowParams{VlanRuleParams: loRuleParams}
467 loFlowParams.CookieSlice = make([]uint64, 0)
468 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
469 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000470 logger.Debugw(ctx, "UniVlanConfigFsm flow add", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000471 "Cookies": oFsm.uniVlanFlowParamsSlice[oFsm.numUniFlows].CookieSlice,
472 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
473 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
Girish Gowdra041dcb32020-11-16 16:54:30 -0800474 "SetPcp": loRuleParams.SetPcp, "numberofFlows": oFsm.numUniFlows + 1,
mpagenko01e726e2020-10-23 09:45:29 +0000475 "device-id": oFsm.deviceID})
476
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000477 oFsm.numUniFlows++
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000478 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
479
480 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
481 logger.Debugw(ctx, "reconciling - skip omci-config of additional vlan rule",
482 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
483 oFsm.mutexFlowParams.Unlock()
484 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000485 _ = pConfigVlanStateBaseFsm.Event(vlanEvSkipOmciConfig)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000486 }
487 return nil
488 }
mpagenko01e726e2020-10-23 09:45:29 +0000489 // note: theoretical it would be possible to clear the same rule from the remove slice
490 // (for entries that have not yet been started with removal)
491 // but that is getting quite complicated - maybe a future optimization in case it should prove reasonable
492 // 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 +0000493
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000494 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
495 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
mpagenko551a4d42020-12-08 18:09:20 +0000496 if oFsm.configuredUniFlow == 0 {
497 // this is a restart with a complete new flow, we can re-use the initial flow config control
498 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenko551a4d42020-12-08 18:09:20 +0000499 go func(a_pBaseFsm *fsm.FSM) {
500 _ = a_pBaseFsm.Event(vlanEvRenew)
501 }(pConfigVlanStateBaseFsm)
502 } else {
503 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000504 //store the actual rule that shall be worked upon in the following transient states
505 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +0000506 //tpId of the next rule to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000507 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko551a4d42020-12-08 18:09:20 +0000508 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, tpID)
509 oFsm.TpIDWaitingFor = tpID
mpagenko9a304ea2020-12-16 15:54:01 +0000510 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request (on setConfig)", log.Fields{
511 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
512 "set-Vlan": oFsm.actualUniVlanConfigRule.SetVid, "tp-id": tpID, "ProfDone": loTechProfDone})
mpagenko551a4d42020-12-08 18:09:20 +0000513 go func(aPBaseFsm *fsm.FSM, aTechProfDone bool) {
514 if aTechProfDone {
515 // let the vlan processing continue with next rule
516 _ = aPBaseFsm.Event(vlanEvIncrFlowConfig)
517 } else {
518 // set to waiting for Techprofile
519 _ = aPBaseFsm.Event(vlanEvWaitTPIncr)
520 }
521 }(pConfigVlanStateBaseFsm, loTechProfDone)
522 }
mpagenko01e726e2020-10-23 09:45:29 +0000523 } // if not in the appropriate state a new entry will be automatically considered later
524 // when the configDone state is reached
mpagenko15ff4a52021-03-02 10:09:20 +0000525 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000526 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000527 logger.Errorw(ctx, "UniVlanConfigFsm flow limit exceeded", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000528 "device-id": oFsm.deviceID, "flow-number": oFsm.numUniFlows})
mpagenko15ff4a52021-03-02 10:09:20 +0000529 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000530 return fmt.Errorf(" UniVlanConfigFsm flow limit exceeded %s", oFsm.deviceID)
531 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000532 } else {
533 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
mpagenkof1fc3862021-02-16 10:09:52 +0000534 kvStoreWrite = true // ensure actual data write to kvStore immediately (no FSM activity)
mpagenko15ff4a52021-03-02 10:09:20 +0000535 oFsm.mutexFlowParams.RLock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000536 if oFsm.numUniFlows == oFsm.configuredUniFlow {
537 //all requested rules really have been configured
538 // state transition notification is checked in deviceHandler
mpagenko15ff4a52021-03-02 10:09:20 +0000539 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000540 if oFsm.pDeviceHandler != nil {
541 //also the related TechProfile was already configured
dbainbri4d3a0dc2020-12-02 00:33:42 +0000542 logger.Debugw(ctx, "UniVlanConfigFsm rule already set - send immediate add-success event for reason update", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +0000543 "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +0000544 // success indication without the need to write to kvStore (done already below with updated data from storePersUniFlowConfig())
545 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetAddNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000546 }
547 } else {
548 // avoid device reason update as the rule config connected to this flow may still be in progress
549 // and the device reason should only be updated on success of rule config
dbainbri4d3a0dc2020-12-02 00:33:42 +0000550 logger.Debugw(ctx, "UniVlanConfigFsm rule already set but configuration ongoing, suppress early add-success event for reason update",
mpagenkofc4f56e2020-11-04 17:17:49 +0000551 log.Fields{"device-id": oFsm.deviceID,
552 "NumberofRules": oFsm.numUniFlows, "Configured rules": oFsm.configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +0000553 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000554 }
555 }
mpagenko01e726e2020-10-23 09:45:29 +0000556
mpagenkof1fc3862021-02-16 10:09:52 +0000557 if flowCookieModify { // some change was done to the flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000558 //permanently store flow config for reconcile case
mpagenko15ff4a52021-03-02 10:09:20 +0000559 oFsm.mutexFlowParams.RLock()
mpagenkof1fc3862021-02-16 10:09:52 +0000560 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
561 &oFsm.uniVlanFlowParamsSlice, kvStoreWrite); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +0000562 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000563 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000564 return err
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000565 }
mpagenko15ff4a52021-03-02 10:09:20 +0000566 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000567 }
568 return nil
569}
570
mpagenkof1fc3862021-02-16 10:09:52 +0000571// VOL-3828 flow config sequence workaround ########### start ##########
572func (oFsm *UniVlanConfigFsm) delayNewRuleForCookie(ctx context.Context, aCookieSlice []uint64) uint64 {
573 //assumes mutexFlowParams.Lock() protection from caller!
574 if oFsm.delayNewRuleCookie == 0 && len(aCookieSlice) == 1 {
575 // if not already waiting, limitation for this workaround is to just have one overlapping cookie/rule
576 // suspend check is done only of there is only one cookie in the request
577 // background: more elements only expected in reconcile use case, where no conflicting sequence is to be expected
578 newCookie := aCookieSlice[0]
579 for _, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
580 for _, cookie := range storedUniFlowParams.CookieSlice {
581 if cookie == newCookie {
582 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - new cookie still exists for some rule", log.Fields{
583 "device-id": oFsm.deviceID, "cookie": cookie, "exists with SetVlan": storedUniFlowParams.VlanRuleParams.SetVid})
584 oFsm.delayNewRuleCookie = newCookie
585 return newCookie //found new cookie in some existing rule
586 }
587 } // for all stored cookies of the actual inspected rule
588 } //for all rules
589 }
590 return 0 //no delay requested
591}
592func (oFsm *UniVlanConfigFsm) suspendNewRule(ctx context.Context) {
593 oFsm.mutexFlowParams.RLock()
594 logger.Infow(ctx, "Need to suspend adding this rule as long as the cookie is still connected to some other rule", log.Fields{
595 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
596 oFsm.mutexFlowParams.RUnlock()
597 select {
598 case <-oFsm.chCookieDeleted:
599 logger.Infow(ctx, "resume adding this rule after having deleted cookie in some other rule", log.Fields{
600 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
601 case <-time.After(time.Duration(cWaitForCookieDeletion) * time.Second):
602 logger.Errorw(ctx, "timeout waiting for deletion of cookie in some other rule, just try to continue", log.Fields{
603 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
604 }
605 oFsm.mutexFlowParams.Lock()
606 oFsm.delayNewRuleCookie = 0
607 oFsm.mutexFlowParams.Unlock()
608}
609func (oFsm *UniVlanConfigFsm) suspendIfRequiredNewRule(ctx context.Context, aCookieSlice []uint64) uint64 {
610 oFsm.mutexFlowParams.Lock()
611 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
612 oFsm.mutexFlowParams.Unlock()
613
614 if delayedCookie != 0 {
615 oFsm.suspendNewRule(ctx)
616 }
617 return delayedCookie
618}
619
620//returns flowModified, RuleAppendRequest
621func (oFsm *UniVlanConfigFsm) reviseFlowConstellation(ctx context.Context, aCookie uint64, aUniVlanRuleParams uniVlanRuleParams) (bool, bool) {
622 flowEntryMatch := false
623 oFsm.mutexFlowParams.Lock()
624 defer oFsm.mutexFlowParams.Unlock()
625 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
626 if storedUniFlowParams.VlanRuleParams == aUniVlanRuleParams {
627 flowEntryMatch = true
628 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - rule already exists", log.Fields{
629 "device-id": oFsm.deviceID})
630 cookieMatch := false
631 for _, cookie := range storedUniFlowParams.CookieSlice {
632 if cookie == aCookie {
633 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - and cookie already exists", log.Fields{
634 "device-id": oFsm.deviceID, "cookie": cookie})
635 cookieMatch = true
636 break //found new cookie - no further search for this requested cookie
637 }
638 }
639 if !cookieMatch {
640 logger.Debugw(ctx, "UniVlanConfigFsm flow revise -adding new cookie", log.Fields{
641 "device-id": oFsm.deviceID, "cookie": aCookie})
642 //as range works with copies of the slice we have to write to the original slice!!
643 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
644 aCookie)
645 return true, false //flowModified, NoRuleAppend
646 }
647 break // found rule - no further rule search
648 }
649 }
650 if !flowEntryMatch { //it is a new rule
651 return true, true //flowModified, RuleAppend
652 }
653 return false, false //flowNotModified, NoRuleAppend
654}
655
656// VOL-3828 flow config sequence workaround ########### end ##########
657
mpagenko01e726e2020-10-23 09:45:29 +0000658//RemoveUniFlowParams verifies on existence of flow cookie,
659// if found removes cookie from flow cookie list and if this is empty
660// initiates removal of the flow related configuration from the ONU (via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000661func (oFsm *UniVlanConfigFsm) RemoveUniFlowParams(ctx context.Context, aCookie uint64) error {
mpagenkof1fc3862021-02-16 10:09:52 +0000662 var deletedCookie uint64
mpagenko01e726e2020-10-23 09:45:29 +0000663 flowCookieMatch := false
664 //mutex protection is required for possible concurrent access to FSM members
665 oFsm.mutexFlowParams.Lock()
666 defer oFsm.mutexFlowParams.Unlock()
mpagenkof1fc3862021-02-16 10:09:52 +0000667remove_loop:
mpagenko01e726e2020-10-23 09:45:29 +0000668 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
669 for i, cookie := range storedUniFlowParams.CookieSlice {
670 if cookie == aCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000671 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - cookie found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000672 "device-id": oFsm.deviceID, "cookie": cookie})
673 flowCookieMatch = true
mpagenkof1fc3862021-02-16 10:09:52 +0000674 deletedCookie = aCookie
675 kvStoreWrite := false //default setting is to not write to kvStore immediately - will be done on FSM execution finally
mpagenko01e726e2020-10-23 09:45:29 +0000676 //remove the cookie from the cookie slice and verify it is getting empty
677 if len(storedUniFlowParams.CookieSlice) == 1 {
mpagenko535d6ef2021-02-26 13:15:34 +0000678 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
679 var cancelPendingConfig bool = false
680 var loRemoveParams uniRemoveVlanFlowParams = uniRemoveVlanFlowParams{}
dbainbri4d3a0dc2020-12-02 00:33:42 +0000681 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - full flow removal", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000682 "device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +0000683 //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 +0000684 // as the one still waiting in the FSM as toAdd but waiting for TechProfileConfig
mpagenko15ff4a52021-03-02 10:09:20 +0000685 // 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 +0000686 // if the Fsm is in some other transient (config) state, we will reach the DelRequest later and correctly process it then
687 if pConfigVlanStateBaseFsm.Is(vlanStWaitingTechProf) {
688 logger.Debugw(ctx, "UniVlanConfigFsm was waiting for TechProf config with this rule, aborting the outstanding config",
689 log.Fields{"device-id": oFsm.deviceID})
690 cancelPendingConfig = true
691 } else {
692 //create a new element for the removeVlanFlow slice
693 loRemoveParams = uniRemoveVlanFlowParams{
694 vlanRuleParams: storedUniFlowParams.VlanRuleParams,
695 cookie: aCookie,
696 }
697 oFsm.uniRemoveFlowsSlice = append(oFsm.uniRemoveFlowsSlice, loRemoveParams)
mpagenko01e726e2020-10-23 09:45:29 +0000698 }
mpagenko01e726e2020-10-23 09:45:29 +0000699
700 //and remove the actual element from the addVlanFlow slice
701 // oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = nil //automatically done by garbage collector
702 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
703 oFsm.numUniFlows = 0 //no more flows
704 oFsm.configuredUniFlow = 0 //no more flows configured
705 oFsm.uniVlanFlowParamsSlice = nil //reset the slice
mpagenko2418ab02020-11-12 12:58:06 +0000706 //at this point it is evident that no flow anymore refers to a still possibly active Techprofile
mpagenko535d6ef2021-02-26 13:15:34 +0000707 //request that this profile gets deleted before a new flow add is allowed (except for some aborted add)
708 if !cancelPendingConfig {
709 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, loRemoveParams.vlanRuleParams.TpID, true)
710 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000711 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - no more flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000712 "device-id": oFsm.deviceID})
713 } else {
714 oFsm.numUniFlows--
715 if oFsm.configuredUniFlow > 0 {
716 oFsm.configuredUniFlow--
717 //TODO!! might be needed to consider still outstanding configure requests ..
718 // so a flow at removal might still not be configured !?!
719 }
mpagenko2418ab02020-11-12 12:58:06 +0000720 usedTpID := storedUniFlowParams.VlanRuleParams.TpID
mpagenko01e726e2020-10-23 09:45:29 +0000721 //cut off the requested flow by slicing out this element
722 oFsm.uniVlanFlowParamsSlice = append(
723 oFsm.uniVlanFlowParamsSlice[:flow], oFsm.uniVlanFlowParamsSlice[flow+1:]...)
mpagenko2418ab02020-11-12 12:58:06 +0000724 //here we have to check, if there are still other flows referencing to the actual ProfileId
725 // before we can request that this profile gets deleted before a new flow add is allowed
mpagenkof1fc3862021-02-16 10:09:52 +0000726 // (needed to extract to function due to lint complexity)
mpagenko535d6ef2021-02-26 13:15:34 +0000727 if !cancelPendingConfig {
728 oFsm.updateTechProfileToDelete(ctx, usedTpID)
729 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000730 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow removed from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000731 "device-id": oFsm.deviceID})
732 }
733 //trigger the FSM to remove the relevant rule
mpagenko535d6ef2021-02-26 13:15:34 +0000734 if cancelPendingConfig {
735 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
mpagenko01e726e2020-10-23 09:45:29 +0000736 go func(a_pBaseFsm *fsm.FSM) {
mpagenko535d6ef2021-02-26 13:15:34 +0000737 _ = a_pBaseFsm.Event(vlanEvCancelOutstandingConfig)
mpagenko01e726e2020-10-23 09:45:29 +0000738 }(pConfigVlanStateBaseFsm)
mpagenko535d6ef2021-02-26 13:15:34 +0000739 } else {
740 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
741 logger.Debugw(ctx, "UniVlanConfigFsm rule removal request", log.Fields{
742 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
743 "tp-id": loRemoveParams.vlanRuleParams.TpID,
744 "set-Vlan": loRemoveParams.vlanRuleParams.SetVid})
745 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
746 // Can't call FSM Event directly, decoupling it
747 go func(a_pBaseFsm *fsm.FSM) {
748 _ = a_pBaseFsm.Event(vlanEvRemFlowConfig)
749 }(pConfigVlanStateBaseFsm)
750 } // if not in the appropriate state a new entry will be automatically considered later
751 // when the configDone state is reached
752 }
mpagenko01e726e2020-10-23 09:45:29 +0000753 } else {
mpagenko01e726e2020-10-23 09:45:29 +0000754 //cut off the requested cookie by slicing out this element
755 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(
756 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[:i],
757 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[i+1:]...)
mpagenkofc4f56e2020-11-04 17:17:49 +0000758 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
mpagenkof1fc3862021-02-16 10:09:52 +0000759 kvStoreWrite = true // ensure actual data write to kvStore immediately (no FSM activity)
mpagenkofc4f56e2020-11-04 17:17:49 +0000760 // state transition notification is checked in deviceHandler
761 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000762 // success indication without the need to write to kvStore (done already below with updated data from storePersUniFlowConfig())
763 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000764 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000765 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - rule persists with still valid cookies", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000766 "device-id": oFsm.deviceID, "cookies": oFsm.uniVlanFlowParamsSlice[flow].CookieSlice})
mpagenkof1fc3862021-02-16 10:09:52 +0000767 if deletedCookie == oFsm.delayNewRuleCookie {
768 //the delayedNewCookie is the one that is currently deleted, but the rule still exist with other cookies
769 //as long as there are further cookies for this rule indicate there is still some cookie to be deleted
770 //simply use the first one
771 oFsm.delayNewRuleCookie = oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[0]
772 logger.Debugw(ctx, "UniVlanConfigFsm remaining cookie awaited for deletion before new rule add", log.Fields{
773 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
774 }
mpagenko01e726e2020-10-23 09:45:29 +0000775 }
mpagenko01e726e2020-10-23 09:45:29 +0000776 //permanently store the modified flow config for reconcile case
mpagenkofc4f56e2020-11-04 17:17:49 +0000777 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000778 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
779 &oFsm.uniVlanFlowParamsSlice, kvStoreWrite); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000780 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +0000781 return err
782 }
mpagenko01e726e2020-10-23 09:45:29 +0000783 }
mpagenkof1fc3862021-02-16 10:09:52 +0000784 break remove_loop //found the cookie - no further search for this requested cookie
mpagenko01e726e2020-10-23 09:45:29 +0000785 }
786 }
mpagenko01e726e2020-10-23 09:45:29 +0000787 } //search all flows
788 if !flowCookieMatch { //some cookie remove-request for a cookie that does not exist in the FSM data
dbainbri4d3a0dc2020-12-02 00:33:42 +0000789 logger.Warnw(ctx, "UniVlanConfigFsm flow removal - remove-cookie not found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000790 "device-id": oFsm.deviceID, "remove-cookie": aCookie})
791 // but accept the request with success as no such cookie (flow) does exist
mpagenkofc4f56e2020-11-04 17:17:49 +0000792 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
793 // state transition notification is checked in deviceHandler
794 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000795 // success indication without the need to write to kvStore (no change)
796 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000797 }
mpagenko01e726e2020-10-23 09:45:29 +0000798 return nil
799 } //unknown cookie
800
801 return nil
802}
803
mpagenkof1fc3862021-02-16 10:09:52 +0000804func (oFsm *UniVlanConfigFsm) updateTechProfileToDelete(ctx context.Context, usedTpID uint8) {
805 //here we have to check, if there are still other flows referencing to the actual ProfileId
806 // before we can request that this profile gets deleted before a new flow add is allowed
807 tpIDInOtherFlows := false
808 for _, tpUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
809 if tpUniFlowParams.VlanRuleParams.TpID == usedTpID {
810 tpIDInOtherFlows = true
811 break // search loop can be left
812 }
813 }
814 if tpIDInOtherFlows {
815 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is still used in other flows", log.Fields{
816 "device-id": oFsm.deviceID, "tp-id": usedTpID})
817 } else {
818 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is not used anymore", log.Fields{
819 "device-id": oFsm.deviceID, "tp-id": usedTpID})
820 //request that this profile gets deleted before a new flow add is allowed
821 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, usedTpID, true)
822 }
823}
824
dbainbri4d3a0dc2020-12-02 00:33:42 +0000825func (oFsm *UniVlanConfigFsm) enterConfigStarting(ctx context.Context, e *fsm.Event) {
826 logger.Debugw(ctx, "UniVlanConfigFsm start", log.Fields{"in state": e.FSM.Current(),
mpagenko01e726e2020-10-23 09:45:29 +0000827 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000828
829 // this FSM is not intended for re-start, needs always new creation for a new run
mpagenko01e726e2020-10-23 09:45:29 +0000830 // (self-destroying - compare enterDisabled())
mpagenkodff5dda2020-08-28 11:52:01 +0000831 oFsm.omciMIdsResponseReceived = make(chan bool)
mpagenkof1fc3862021-02-16 10:09:52 +0000832 oFsm.chCookieDeleted = make(chan bool)
mpagenkodff5dda2020-08-28 11:52:01 +0000833 // start go routine for processing of LockState messages
dbainbri4d3a0dc2020-12-02 00:33:42 +0000834 go oFsm.processOmciVlanMessages(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +0000835 //let the state machine run forward from here directly
836 pConfigVlanStateAFsm := oFsm.pAdaptFsm
837 if pConfigVlanStateAFsm != nil {
mpagenko9a304ea2020-12-16 15:54:01 +0000838
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000839 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
840 logger.Debugw(ctx, "reconciling - skip omci-config of vlan rule",
841 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
842 go func(a_pAFsm *AdapterFsm) {
843 _ = a_pAFsm.pFsm.Event(vlanEvSkipOmciConfig)
844 }(pConfigVlanStateAFsm)
845 return
846 }
847 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +0000848 //possibly the entry is not valid anymore based on intermediate delete requests
849 //just a basic protection ...
850 if len(oFsm.uniVlanFlowParamsSlice) == 0 {
851 oFsm.mutexFlowParams.Unlock()
852 logger.Debugw(ctx, "UniVlanConfigFsm start: no rule entry anymore available", log.Fields{
853 "device-id": oFsm.deviceID})
854 // Can't call FSM Event directly, decoupling it
855 go func(a_pAFsm *AdapterFsm) {
856 _ = a_pAFsm.pFsm.Event(vlanEvReset)
857 }(pConfigVlanStateAFsm)
858 return
859 }
mpagenko9a304ea2020-12-16 15:54:01 +0000860 //access to uniVlanFlowParamsSlice is done on first element only here per definition
861 //store the actual rule that shall be worked upon in the following transient states
862 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[0].VlanRuleParams
mpagenko9a304ea2020-12-16 15:54:01 +0000863 tpID := oFsm.actualUniVlanConfigRule.TpID
864 oFsm.TpIDWaitingFor = tpID
mpagenko551a4d42020-12-08 18:09:20 +0000865 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID))
mpagenko9a304ea2020-12-16 15:54:01 +0000866 logger.Debugw(ctx, "UniVlanConfigFsm - start with first rule", log.Fields{
867 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
868 "set-Vlan": oFsm.actualUniVlanConfigRule.SetVid, "tp-id": tpID, "ProfDone": loTechProfDone})
mpagenko551a4d42020-12-08 18:09:20 +0000869 //cmp also usage in EVTOCDE create in omci_cc
870 oFsm.evtocdID = macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo)
mpagenko535d6ef2021-02-26 13:15:34 +0000871 oFsm.mutexFlowParams.Unlock()
mpagenko9a304ea2020-12-16 15:54:01 +0000872 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +0000873 go func(aPAFsm *AdapterFsm, aTechProfDone bool) {
874 if aPAFsm != nil && aPAFsm.pFsm != nil {
875 if aTechProfDone {
mpagenkodff5dda2020-08-28 11:52:01 +0000876 // let the vlan processing begin
mpagenko551a4d42020-12-08 18:09:20 +0000877 _ = aPAFsm.pFsm.Event(vlanEvStartConfig)
mpagenkodff5dda2020-08-28 11:52:01 +0000878 } else {
879 // set to waiting for Techprofile
mpagenko551a4d42020-12-08 18:09:20 +0000880 _ = aPAFsm.pFsm.Event(vlanEvWaitTechProf)
mpagenkodff5dda2020-08-28 11:52:01 +0000881 }
882 }
mpagenko551a4d42020-12-08 18:09:20 +0000883 }(pConfigVlanStateAFsm, loTechProfDone)
884 } else {
885 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
886 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
887 //should never happen, else: recovery would be needed from outside the FSM
888 return
mpagenkodff5dda2020-08-28 11:52:01 +0000889 }
890}
891
dbainbri4d3a0dc2020-12-02 00:33:42 +0000892func (oFsm *UniVlanConfigFsm) enterConfigVtfd(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000893 //mutex protection is required for possible concurrent access to FSM members
894 oFsm.mutexFlowParams.Lock()
mpagenko551a4d42020-12-08 18:09:20 +0000895 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
mpagenko9a304ea2020-12-16 15:54:01 +0000896 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +0000897 // meaning transparent setup - no specific VTFD setting required
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000898 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000899 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000900 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000901 // let the FSM proceed ... (from within this state all internal pointers may be expected to be correct)
mpagenkodff5dda2020-08-28 11:52:01 +0000902 pConfigVlanStateAFsm := oFsm.pAdaptFsm
mpagenko9a304ea2020-12-16 15:54:01 +0000903 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +0000904 go func(a_pAFsm *AdapterFsm) {
Himani Chawla4d908332020-08-31 12:30:20 +0530905 _ = a_pAFsm.pFsm.Event(vlanEvRxConfigVtfd)
mpagenkodff5dda2020-08-28 11:52:01 +0000906 }(pConfigVlanStateAFsm)
907 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300908 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
909 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
mpagenko9a304ea2020-12-16 15:54:01 +0000910 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + uint16(oFsm.actualUniVlanConfigRule.TpID)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000911 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300912 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000913 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
914 // setVid is assumed to be masked already by the caller to 12 bit
mpagenko9a304ea2020-12-16 15:54:01 +0000915 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000916 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000917 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000918 vtfdFilterList[0] = oFsm.vlanFilterList[0]
919 oFsm.numVlanFilterEntries = 1
mpagenkodff5dda2020-08-28 11:52:01 +0000920 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300921 EntityID: vtfdID,
mpagenkodff5dda2020-08-28 11:52:01 +0000922 Attributes: me.AttributeValueMap{
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000923 "VlanFilterList": vtfdFilterList, //omci lib wants a slice for serialization
924 "ForwardOperation": uint8(0x10), //VID investigation
925 "NumberOfEntries": oFsm.numVlanFilterEntries,
mpagenkodff5dda2020-08-28 11:52:01 +0000926 },
927 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000928 logger.Debugw(ctx, "UniVlanConfigFsm sendcreate VTFD", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000929 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Girish Gowdra0b235842021-03-09 13:06:46 -0800930 meInstance := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +0000931 oFsm.pAdaptFsm.commChan, meParams)
932 //accept also nil as (error) return value for writing to LastTx
933 // - this avoids misinterpretation of new received OMCI messages
934 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
935 // send shall return (dual format) error code that can be used here for immediate error treatment
936 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +0000937 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +0000938 }
939}
940
dbainbri4d3a0dc2020-12-02 00:33:42 +0000941func (oFsm *UniVlanConfigFsm) enterConfigEvtocd(ctx context.Context, e *fsm.Event) {
942 logger.Debugw(ctx, "UniVlanConfigFsm - start config EVTOCD loop", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000943 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +0000944 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300945 go func() {
mpagenko9a304ea2020-12-16 15:54:01 +0000946 //using the first element in the slice because it's the first flow per definition here
947 errEvto := oFsm.performConfigEvtocdEntries(ctx, 0)
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300948 //This is correct passing scenario
949 if errEvto == nil {
mpagenko9a304ea2020-12-16 15:54:01 +0000950 tpID := oFsm.actualUniVlanConfigRule.TpID
951 vlanID := oFsm.actualUniVlanConfigRule.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +0000952 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
953 logger.Infow(ctx, "Setting multicast MEs, with first flow", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300954 "techProfile": tpID, "gemPort": gemPort, "vlanID": vlanID, "configuredUniFlow": oFsm.configuredUniFlow})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000955 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300956 vlanID)
957 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000958 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300959 log.Fields{"device-id": oFsm.deviceID})
960 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
961 }
962 }
963 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
964 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
965 }
966 }()
mpagenkodff5dda2020-08-28 11:52:01 +0000967}
968
dbainbri4d3a0dc2020-12-02 00:33:42 +0000969func (oFsm *UniVlanConfigFsm) enterVlanConfigDone(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000970
mpagenko9a304ea2020-12-16 15:54:01 +0000971 oFsm.mutexFlowParams.RLock()
972 defer oFsm.mutexFlowParams.RUnlock()
973
mpagenkof1fc3862021-02-16 10:09:52 +0000974 logger.Infow(ctx, "UniVlanConfigFsm config done - checking on more flows", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +0000975 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
976 "overall-uni-rules": oFsm.numUniFlows, "configured-uni-rules": oFsm.configuredUniFlow})
977 pConfigVlanStateAFsm := oFsm.pAdaptFsm
978 if pConfigVlanStateAFsm == nil {
mpagenko551a4d42020-12-08 18:09:20 +0000979 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
980 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
981 //should never happen, else: recovery would be needed from outside the FSM
982 return
983 }
984 pConfigVlanStateBaseFsm := pConfigVlanStateAFsm.pFsm
mpagenko01e726e2020-10-23 09:45:29 +0000985 if len(oFsm.uniRemoveFlowsSlice) > 0 {
986 //some further flows are to be removed, removal always starts with the first element
mpagenko9a304ea2020-12-16 15:54:01 +0000987 logger.Debugw(ctx, "UniVlanConfigFsm rule removal from ConfigDone", log.Fields{
988 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
989 "tp-id": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.TpID,
990 "set-Vlan": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.SetVid})
991 // Can't call FSM Event directly, decoupling it
mpagenko01e726e2020-10-23 09:45:29 +0000992 go func(a_pBaseFsm *fsm.FSM) {
993 _ = a_pBaseFsm.Event(vlanEvRemFlowConfig)
994 }(pConfigVlanStateBaseFsm)
995 return
996 }
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +0000997 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
998 oFsm.configuredUniFlow = oFsm.numUniFlows
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000999 if !oFsm.pDeviceHandler.isReconcilingFlows() {
1000 logger.Debugw(ctx, "reconciling - flow processing finished", log.Fields{"device-id": oFsm.deviceID})
1001 oFsm.pDeviceHandler.chReconcilingFlowsFinished <- true
1002 }
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001003 logger.Debugw(ctx, "reconciling - skip enterVlanConfigDone processing",
1004 log.Fields{"numUniFlows": oFsm.numUniFlows, "configuredUniFlow": oFsm.configuredUniFlow, "device-id": oFsm.deviceID})
1005 return
1006 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001007 if oFsm.numUniFlows > oFsm.configuredUniFlow {
mpagenko551a4d42020-12-08 18:09:20 +00001008 if oFsm.configuredUniFlow == 0 {
mpagenko551a4d42020-12-08 18:09:20 +00001009 // this is a restart with a complete new flow, we can re-use the initial flow config control
1010 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenko9a304ea2020-12-16 15:54:01 +00001011 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001012 go func(a_pBaseFsm *fsm.FSM) {
1013 _ = a_pBaseFsm.Event(vlanEvRenew)
1014 }(pConfigVlanStateBaseFsm)
1015 return
1016 }
1017
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001018 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001019 //store the actual rule that shall be worked upon in the following transient states
1020 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +00001021 //tpId of the next rule to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001022 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko551a4d42020-12-08 18:09:20 +00001023 oFsm.TpIDWaitingFor = tpID
mpagenko551a4d42020-12-08 18:09:20 +00001024 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, tpID)
mpagenko9a304ea2020-12-16 15:54:01 +00001025 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request", log.Fields{
1026 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
1027 "set-Vlan": oFsm.actualUniVlanConfigRule.SetVid, "tp-id": tpID, "ProfDone": loTechProfDone})
1028 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001029 go func(aPBaseFsm *fsm.FSM, aTechProfDone bool) {
1030 if aTechProfDone {
1031 // let the vlan processing continue with next rule
1032 _ = aPBaseFsm.Event(vlanEvIncrFlowConfig)
1033 } else {
1034 // set to waiting for Techprofile
1035 _ = aPBaseFsm.Event(vlanEvWaitTPIncr)
1036 }
1037 }(pConfigVlanStateBaseFsm, loTechProfDone)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001038 return
1039 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001040 logger.Debugw(ctx, "UniVlanConfigFsm - VLAN config done: send dh event notification", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001041 "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001042 // it might appear that some flows are requested also after 'flowPushed' event has been generated ...
1043 // state transition notification is checked in deviceHandler
mpagenko551a4d42020-12-08 18:09:20 +00001044 // note: 'flowPushed' event is only generated if all 'pending' rules are configured
mpagenkodff5dda2020-08-28 11:52:01 +00001045 if oFsm.pDeviceHandler != nil {
mpagenkofc4f56e2020-11-04 17:17:49 +00001046 //making use of the add->remove successor enum assumption/definition
dbainbri4d3a0dc2020-12-02 00:33:42 +00001047 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(uint8(oFsm.requestEvent)+oFsm.requestEventOffset))
mpagenkodff5dda2020-08-28 11:52:01 +00001048 }
1049}
1050
dbainbri4d3a0dc2020-12-02 00:33:42 +00001051func (oFsm *UniVlanConfigFsm) enterConfigIncrFlow(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001052
1053 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
1054 logger.Debugw(ctx, "reconciling - skip further processing for incremental flow",
1055 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
1056 go func(a_pBaseFsm *fsm.FSM) {
1057 _ = a_pBaseFsm.Event(vlanEvSkipIncFlowConfig)
1058 }(oFsm.pAdaptFsm.pFsm)
1059 return
1060 }
mpagenko15ff4a52021-03-02 10:09:20 +00001061 oFsm.mutexFlowParams.Lock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001062 logger.Debugw(ctx, "UniVlanConfigFsm - start config further incremental flow", log.Fields{
Girish Gowdra041dcb32020-11-16 16:54:30 -08001063 "in state": e.FSM.Current(), "recent flow-number": oFsm.configuredUniFlow,
mpagenko01e726e2020-10-23 09:45:29 +00001064 "device-id": oFsm.deviceID})
mpagenko551a4d42020-12-08 18:09:20 +00001065 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001066
mpagenko9a304ea2020-12-16 15:54:01 +00001067 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001068 // meaning transparent setup - no specific VTFD setting required
1069 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001070 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001071 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001072 } else {
1073 if oFsm.numVlanFilterEntries == 0 {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001074 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1075 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
mpagenko9a304ea2020-12-16 15:54:01 +00001076 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + uint16(oFsm.actualUniVlanConfigRule.TpID)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001077 //no VTFD yet created
dbainbri4d3a0dc2020-12-02 00:33:42 +00001078 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001079 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001080 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001081 // 'SetVid' below is assumed to be masked already by the caller to 12 bit
mpagenko9a304ea2020-12-16 15:54:01 +00001082 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001083
mpagenko01e726e2020-10-23 09:45:29 +00001084 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001085 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1086 oFsm.numVlanFilterEntries = 1
1087 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001088 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001089 Attributes: me.AttributeValueMap{
1090 "VlanFilterList": vtfdFilterList,
1091 "ForwardOperation": uint8(0x10), //VID investigation
1092 "NumberOfEntries": oFsm.numVlanFilterEntries,
1093 },
1094 }
Girish Gowdra0b235842021-03-09 13:06:46 -08001095 meInstance := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001096 oFsm.pAdaptFsm.commChan, meParams)
1097 //accept also nil as (error) return value for writing to LastTx
1098 // - this avoids misinterpretation of new received OMCI messages
1099 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1100 // send shall return (dual format) error code that can be used here for immediate error treatment
1101 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001102 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001103 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001104 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1105 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
mpagenko551a4d42020-12-08 18:09:20 +00001106 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID +
mpagenko9a304ea2020-12-16 15:54:01 +00001107 uint16(oFsm.actualUniVlanConfigRule.TpID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001108
dbainbri4d3a0dc2020-12-02 00:33:42 +00001109 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001110 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001111 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001112 // setVid is assumed to be masked already by the caller to 12 bit
1113 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] =
mpagenko9a304ea2020-12-16 15:54:01 +00001114 uint16(oFsm.actualUniVlanConfigRule.SetVid)
mpagenko01e726e2020-10-23 09:45:29 +00001115 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001116
1117 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
1118 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
1119 // new vlan associated with a different TP.
mpagenko9a304ea2020-12-16 15:54:01 +00001120 vtfdFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001121
1122 oFsm.numVlanFilterEntries++
1123 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001124 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001125 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001126 "VlanFilterList": vtfdFilterList,
1127 "ForwardOperation": uint8(0x10), //VID investigation
1128 "NumberOfEntries": oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001129 },
1130 }
Girish Gowdra0b235842021-03-09 13:06:46 -08001131 meInstance := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001132 oFsm.pAdaptFsm.commChan, meParams)
1133 //accept also nil as (error) return value for writing to LastTx
1134 // - this avoids misinterpretation of new received OMCI messages
1135 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1136 // send shall return (dual format) error code that can be used here for immediate error treatment
1137 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001138 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001139 }
mpagenko15ff4a52021-03-02 10:09:20 +00001140 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001141 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001142 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001143 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001144 logger.Errorw(ctx, "VTFD create/set failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001145 log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001146 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001147 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001148 go func(a_pBaseFsm *fsm.FSM) {
1149 _ = a_pBaseFsm.Event(vlanEvReset)
1150 }(pConfigVlanStateBaseFsm)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001151 return
1152 }
1153 }
mpagenko15ff4a52021-03-02 10:09:20 +00001154 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001155 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
mpagenko15ff4a52021-03-02 10:09:20 +00001156 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001157 go func() {
mpagenko15ff4a52021-03-02 10:09:20 +00001158 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001159 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko15ff4a52021-03-02 10:09:20 +00001160 configuredUniFlow := oFsm.configuredUniFlow
1161 oFsm.mutexFlowParams.RUnlock()
1162 errEvto := oFsm.performConfigEvtocdEntries(ctx, configuredUniFlow)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001163 //This is correct passing scenario
1164 if errEvto == nil {
1165 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
dbainbri4d3a0dc2020-12-02 00:33:42 +00001166 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
mpagenko15ff4a52021-03-02 10:09:20 +00001167 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001168 vlanID := oFsm.actualUniVlanConfigRule.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +00001169 logger.Infow(ctx, "Setting multicast MEs for additional flows", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001170 "techProfile": tpID, "gemPort": gemPort,
1171 "vlanID": vlanID, "configuredUniFlow": oFsm.configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +00001172 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001173 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001174 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001175 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001176 log.Fields{"device-id": oFsm.deviceID})
1177 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1178 }
1179 }
1180 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
1181 }
1182 }()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001183}
1184
dbainbri4d3a0dc2020-12-02 00:33:42 +00001185func (oFsm *UniVlanConfigFsm) enterRemoveFlow(ctx context.Context, e *fsm.Event) {
mpagenko551a4d42020-12-08 18:09:20 +00001186 oFsm.mutexFlowParams.RLock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001187 logger.Debugw(ctx, "UniVlanConfigFsm - start removing the top remove-flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001188 "in state": e.FSM.Current(), "with last cookie": oFsm.uniRemoveFlowsSlice[0].cookie,
1189 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001190
mpagenkofc4f56e2020-11-04 17:17:49 +00001191 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
1192 loAllowSpecificOmciConfig := oFsm.pDeviceHandler.ReadyForSpecificOmciConfig
mpagenko01e726e2020-10-23 09:45:29 +00001193 loVlanEntryClear := uint8(0)
1194 loVlanEntryRmPos := uint8(0x80) //with indication 'invalid' in bit 7
1195 //shallow copy is sufficient as no reference variables are used within struct
1196 loRuleParams := oFsm.uniRemoveFlowsSlice[0].vlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +00001197 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001198 logger.Debugw(ctx, "UniVlanConfigFsm - remove-flow parameters are", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001199 "match vid": loRuleParams.MatchVid, "match Pcp": loRuleParams.MatchPcp,
1200 "set vid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
1201 "device-id": oFsm.deviceID})
1202
1203 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
1204 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001205 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD removal required for transparent flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001206 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1207 } else {
1208 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization and 're-copy'
1209 if oFsm.numVlanFilterEntries == 1 {
mpagenko551a4d42020-12-08 18:09:20 +00001210 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + uint16(loRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00001211 //only one active VLAN entry (hopefully the SetVID we want to remove - should be, but not verified ..)
1212 // so we can just delete the VTFD entry
dbainbri4d3a0dc2020-12-02 00:33:42 +00001213 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD delete (no more vlan filters)",
mpagenko01e726e2020-10-23 09:45:29 +00001214 log.Fields{"current vlan list": oFsm.vlanFilterList,
1215 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001216 loVlanEntryClear = 1 //full VlanFilter clear request
1217 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
Girish Gowdra0b235842021-03-09 13:06:46 -08001218 meInstance := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001219 oFsm.pAdaptFsm.commChan, vtfdID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001220 oFsm.pLastTxMeInstance = meInstance
1221 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001222 logger.Debugw(ctx, "UniVlanConfigFsm delete VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001223 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.getDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +00001224 }
mpagenko01e726e2020-10-23 09:45:29 +00001225 } else {
1226 //many VTFD already should exists - find and remove the one concerned by the actual remove rule
1227 // by updating the VTFD per set command with new valid list
dbainbri4d3a0dc2020-12-02 00:33:42 +00001228 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD removal of requested VLAN from the list on OMCI",
mpagenko01e726e2020-10-23 09:45:29 +00001229 log.Fields{"current vlan list": oFsm.vlanFilterList,
1230 "set-vlan": loRuleParams.SetVid, "device-id": oFsm.deviceID})
1231 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1232 if loRuleParams.SetVid == uint32(oFsm.vlanFilterList[i]) {
1233 loVlanEntryRmPos = i
1234 break //abort search
1235 }
1236 }
1237 if loVlanEntryRmPos < cVtfdTableSize {
mpagenko551a4d42020-12-08 18:09:20 +00001238 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + uint16(loRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00001239 //valid entry was found - to be eclipsed
1240 loVlanEntryClear = 2 //VlanFilter remove request for a specific entry
1241 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1242 if i < loVlanEntryRmPos {
1243 vtfdFilterList[i] = oFsm.vlanFilterList[i] //copy original
1244 } else if i < (cVtfdTableSize - 1) {
1245 vtfdFilterList[i] = oFsm.vlanFilterList[i+1] //copy successor (including 0 elements)
1246 } else {
1247 vtfdFilterList[i] = 0 //set last byte if needed
1248 }
1249 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001250 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001251 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001252 "new vlan list": vtfdFilterList, "device-id": oFsm.deviceID})
1253
mpagenkofc4f56e2020-11-04 17:17:49 +00001254 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001255 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
Girish Gowdra0b235842021-03-09 13:06:46 -08001256 meInstance := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001257 oFsm.pAdaptFsm.commChan, vtfdID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001258 oFsm.pLastTxMeInstance = meInstance
1259 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001260 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001261 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.getDeviceReasonString()})
mpagenko01e726e2020-10-23 09:45:29 +00001262 }
mpagenko01e726e2020-10-23 09:45:29 +00001263 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001264 logger.Warnw(ctx, "UniVlanConfigFsm: requested VLAN for removal not found in list - ignore and continue (no VTFD set)",
mpagenko01e726e2020-10-23 09:45:29 +00001265 log.Fields{"device-id": oFsm.deviceID})
1266 }
1267 }
1268 if loVlanEntryClear > 0 {
mpagenkofc4f56e2020-11-04 17:17:49 +00001269 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
1270 //waiting on response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001271 err := oFsm.waitforOmciResponse(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001272 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001273 logger.Errorw(ctx, "VTFD delete/reset failed, aborting VlanConfig FSM!",
mpagenkofc4f56e2020-11-04 17:17:49 +00001274 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001275 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001276 go func(a_pBaseFsm *fsm.FSM) {
1277 _ = a_pBaseFsm.Event(vlanEvReset)
1278 }(pConfigVlanStateBaseFsm)
1279 return
1280 }
mpagenko01e726e2020-10-23 09:45:29 +00001281 }
1282
mpagenko15ff4a52021-03-02 10:09:20 +00001283 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00001284 if loVlanEntryClear == 1 {
1285 oFsm.vlanFilterList[0] = 0 //first entry is the only that can contain the previous only-one element
1286 oFsm.numVlanFilterEntries = 0
1287 } else if loVlanEntryClear == 2 {
1288 // new VlanFilterList should be one entry smaller now - copy from last configured entry
1289 // this loop now includes the 0 element on previous last valid entry
1290 for i := uint8(0); i <= oFsm.numVlanFilterEntries; i++ {
1291 oFsm.vlanFilterList[i] = vtfdFilterList[i]
1292 }
1293 oFsm.numVlanFilterEntries--
1294 }
mpagenko15ff4a52021-03-02 10:09:20 +00001295 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001296 }
1297 }
1298
mpagenkofc4f56e2020-11-04 17:17:49 +00001299 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001300 go oFsm.removeEvtocdEntries(ctx, loRuleParams)
mpagenkofc4f56e2020-11-04 17:17:49 +00001301 } else {
1302 // OMCI processing is not done, expectation is to have the ONU in some basic config state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001303 logger.Debugw(ctx, "UniVlanConfigFsm remove EVTOCD OMCI handling skipped based on device state", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +00001304 "device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001305 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001306 go func(a_pBaseFsm *fsm.FSM) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001307 _ = a_pBaseFsm.Event(vlanEvRemFlowDone, loRuleParams.TpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001308 }(pConfigVlanStateBaseFsm)
1309 }
mpagenkodff5dda2020-08-28 11:52:01 +00001310}
1311
dbainbri4d3a0dc2020-12-02 00:33:42 +00001312func (oFsm *UniVlanConfigFsm) enterVlanCleanupDone(ctx context.Context, e *fsm.Event) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001313 var tpID uint8
1314 // Extract the tpID
1315 if len(e.Args) > 0 {
1316 tpID = e.Args[0].(uint8)
1317 logger.Debugw(ctx, "UniVlanConfigFsm - flow removed for tp id", log.Fields{"device-id": oFsm.deviceID, "tpID": e.Args[0].(uint8)})
1318 } else {
1319 logger.Warnw(ctx, "UniVlanConfigFsm - tp id not available", log.Fields{"device-id": oFsm.deviceID})
1320 }
mpagenko01e726e2020-10-23 09:45:29 +00001321 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001322 deletedCookie := oFsm.uniRemoveFlowsSlice[0].cookie
1323 logger.Debugw(ctx, "UniVlanConfigFsm - removing the removal data", log.Fields{
1324 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1325 "removed cookie": deletedCookie, "waitForDeleteCookie": oFsm.delayNewRuleCookie})
1326
mpagenko01e726e2020-10-23 09:45:29 +00001327 if len(oFsm.uniRemoveFlowsSlice) <= 1 {
1328 oFsm.uniRemoveFlowsSlice = nil //reset the slice
dbainbri4d3a0dc2020-12-02 00:33:42 +00001329 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - last remove-flow deleted", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001330 "device-id": oFsm.deviceID})
1331 } else {
1332 //cut off the actual flow by slicing out the first element
1333 oFsm.uniRemoveFlowsSlice = append(
1334 oFsm.uniRemoveFlowsSlice[:0],
1335 oFsm.uniRemoveFlowsSlice[1:]...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001336 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow deleted from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001337 "device-id": oFsm.deviceID})
1338 }
1339 oFsm.mutexFlowParams.Unlock()
1340
mpagenkof1fc3862021-02-16 10:09:52 +00001341 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
mpagenko01e726e2020-10-23 09:45:29 +00001342 //return to the basic config verification state
mpagenkodff5dda2020-08-28 11:52:01 +00001343 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1344 if pConfigVlanStateAFsm != nil {
mpagenko9a304ea2020-12-16 15:54:01 +00001345 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +00001346 go func(a_pAFsm *AdapterFsm) {
1347 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001348 _ = a_pAFsm.pFsm.Event(vlanEvFlowDataRemoved)
mpagenkodff5dda2020-08-28 11:52:01 +00001349 }
1350 }(pConfigVlanStateAFsm)
1351 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001352
1353 oFsm.mutexFlowParams.RLock()
1354 noOfFlowRem := len(oFsm.uniRemoveFlowsSlice)
mpagenkof1fc3862021-02-16 10:09:52 +00001355 if deletedCookie == oFsm.delayNewRuleCookie {
1356 // flush the channel CookieDeleted to ensure it is not lingering from some previous (aborted) activity
1357 select {
1358 case <-oFsm.chCookieDeleted:
1359 logger.Debug(ctx, "flushed CookieDeleted")
1360 default:
1361 }
1362 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue
1363 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001364 oFsm.mutexFlowParams.RUnlock()
1365 // If all pending flow removes are completed and TP ID is valid, processing any pending TP delete
1366 if noOfFlowRem == 0 && tpID > 0 {
1367 logger.Debugw(ctx, "processing pending tp delete", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID})
1368 // If we are here then all flows are removed.
1369 oFsm.pDeviceHandler.ProcessPendingTpDelete(ctx, oFsm.pOnuUniPort, tpID)
1370 }
mpagenkodff5dda2020-08-28 11:52:01 +00001371}
1372
dbainbri4d3a0dc2020-12-02 00:33:42 +00001373func (oFsm *UniVlanConfigFsm) enterResetting(ctx context.Context, e *fsm.Event) {
1374 logger.Debugw(ctx, "UniVlanConfigFsm resetting", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001375
1376 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1377 if pConfigVlanStateAFsm != nil {
1378 // abort running message processing
1379 fsmAbortMsg := Message{
1380 Type: TestMsg,
1381 Data: TestMessage{
1382 TestMessageVal: AbortMessageProcessing,
1383 },
1384 }
1385 pConfigVlanStateAFsm.commChan <- fsmAbortMsg
1386
mpagenko9a304ea2020-12-16 15:54:01 +00001387 //try to restart the FSM to 'disabled'
1388 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +00001389 go func(a_pAFsm *AdapterFsm) {
1390 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301391 _ = a_pAFsm.pFsm.Event(vlanEvRestart)
mpagenkodff5dda2020-08-28 11:52:01 +00001392 }
1393 }(pConfigVlanStateAFsm)
1394 }
1395}
1396
dbainbri4d3a0dc2020-12-02 00:33:42 +00001397func (oFsm *UniVlanConfigFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
1398 logger.Debugw(ctx, "UniVlanConfigFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001399 oFsm.pLastTxMeInstance = nil
mpagenkodff5dda2020-08-28 11:52:01 +00001400 if oFsm.pDeviceHandler != nil {
mpagenko2418ab02020-11-12 12:58:06 +00001401 //TODO: to clarify with improved error treatment for VlanConfigFsm (timeout,reception) errors
1402 // current code removes the complete FSM including all flow/rule configuration done so far
1403 // this might be a bit to much, it would require fully new flow config from rwCore (at least on OnuDown/up)
1404 // maybe a more sophisticated approach is possible without clearing the data
mpagenko9a304ea2020-12-16 15:54:01 +00001405 oFsm.mutexFlowParams.RLock()
mpagenko2418ab02020-11-12 12:58:06 +00001406 if oFsm.clearPersistency {
1407 //permanently remove possibly stored persistent data
1408 if len(oFsm.uniVlanFlowParamsSlice) > 0 {
1409 var emptySlice = make([]uniVlanFlowParams, 0)
mpagenkof1fc3862021-02-16 10:09:52 +00001410 _ = oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID, &emptySlice, true) //ignore errors
mpagenko2418ab02020-11-12 12:58:06 +00001411 }
1412 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001413 logger.Debugw(ctx, "UniVlanConfigFsm persistency data not cleared", log.Fields{"device-id": oFsm.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001414 }
mpagenkof1fc3862021-02-16 10:09:52 +00001415 if oFsm.delayNewRuleCookie != 0 {
1416 // looks like the waiting AddFlow is stuck
1417 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue/treminate
1418 }
mpagenko9a304ea2020-12-16 15:54:01 +00001419 oFsm.mutexFlowParams.RUnlock()
mpagenko2418ab02020-11-12 12:58:06 +00001420 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001421 go oFsm.pDeviceHandler.RemoveVlanFilterFsm(ctx, oFsm.pOnuUniPort)
mpagenkodff5dda2020-08-28 11:52:01 +00001422 }
1423}
1424
dbainbri4d3a0dc2020-12-02 00:33:42 +00001425func (oFsm *UniVlanConfigFsm) processOmciVlanMessages(ctx context.Context) { //ctx context.Context?
1426 logger.Debugw(ctx, "Start UniVlanConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001427loop:
1428 for {
mpagenkodff5dda2020-08-28 11:52:01 +00001429 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00001430 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001431 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +05301432 message, ok := <-oFsm.pAdaptFsm.commChan
1433 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001434 logger.Info(ctx, "UniVlanConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301435 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
1436 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1437 break loop
1438 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001439 logger.Debugw(ctx, "UniVlanConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301440
1441 switch message.Type {
1442 case TestMsg:
1443 msg, _ := message.Data.(TestMessage)
1444 if msg.TestMessageVal == AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001445 logger.Infow(ctx, "UniVlanConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001446 break loop
1447 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001448 logger.Warnw(ctx, "UniVlanConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Himani Chawla4d908332020-08-31 12:30:20 +05301449 case OMCI:
1450 msg, _ := message.Data.(OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001451 oFsm.handleOmciVlanConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301452 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001453 logger.Warn(ctx, "UniVlanConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301454 "message.Type": message.Type})
mpagenkodff5dda2020-08-28 11:52:01 +00001455 }
1456 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001457 logger.Infow(ctx, "End UniVlanConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001458}
1459
dbainbri4d3a0dc2020-12-02 00:33:42 +00001460func (oFsm *UniVlanConfigFsm) handleOmciVlanConfigMessage(ctx context.Context, msg OmciMessage) {
1461 logger.Debugw(ctx, "Rx OMCI UniVlanConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001462 "msgType": msg.OmciMsg.MessageType})
1463
1464 switch msg.OmciMsg.MessageType {
1465 case omci.CreateResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001466 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001467 if err := oFsm.handleOmciCreateResponseMessage(ctx, msg.OmciPacket); err != nil {
1468 logger.Warnw(ctx, "CreateResponse handling aborted", log.Fields{"err": err})
mpagenkodff5dda2020-08-28 11:52:01 +00001469 return
1470 }
mpagenkodff5dda2020-08-28 11:52:01 +00001471 } //CreateResponseType
1472 case omci.SetResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001473 { //leave that here as direct code as most often used
mpagenkodff5dda2020-08-28 11:52:01 +00001474 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1475 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001476 logger.Errorw(ctx, "Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001477 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001478 return
1479 }
1480 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1481 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001482 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001483 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001484 return
1485 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001486 logger.Debugw(ctx, "UniVlanConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkodff5dda2020-08-28 11:52:01 +00001487 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001488 logger.Errorw(ctx, "UniVlanConfigFsm Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001489 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
mpagenkodff5dda2020-08-28 11:52:01 +00001490 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1491 return
1492 }
mpagenko01e726e2020-10-23 09:45:29 +00001493 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1494 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1495 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001496 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "MulticastOperationsProfile":
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001497 { // let the MultiEntity config proceed by stopping the wait function
mpagenkodff5dda2020-08-28 11:52:01 +00001498 oFsm.omciMIdsResponseReceived <- true
1499 }
1500 }
1501 }
1502 } //SetResponseType
mpagenko01e726e2020-10-23 09:45:29 +00001503 case omci.DeleteResponseType:
1504 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001505 if err := oFsm.handleOmciDeleteResponseMessage(ctx, msg.OmciPacket); err != nil {
1506 logger.Warnw(ctx, "DeleteResponse handling aborted", log.Fields{"err": err})
mpagenko01e726e2020-10-23 09:45:29 +00001507 return
1508 }
1509 } //DeleteResponseType
mpagenkodff5dda2020-08-28 11:52:01 +00001510 default:
1511 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001512 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00001513 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001514 return
1515 }
1516 }
1517}
1518
dbainbri4d3a0dc2020-12-02 00:33:42 +00001519func (oFsm *UniVlanConfigFsm) handleOmciCreateResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00001520 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeCreateResponse)
1521 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001522 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001523 log.Fields{"device-id": oFsm.deviceID})
1524 return fmt.Errorf("omci msg layer could not be detected for CreateResponse for device-id %x",
1525 oFsm.deviceID)
1526 }
1527 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
1528 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001529 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001530 log.Fields{"device-id": oFsm.deviceID})
1531 return fmt.Errorf("omci msg layer could not be assigned for CreateResponse for device-id %x",
1532 oFsm.deviceID)
1533 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001534 logger.Debugw(ctx, "UniVlanConfigFsm CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001535 if msgObj.Result != me.Success && msgObj.Result != me.InstanceExists {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001536 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"device-id": oFsm.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00001537 "Error": msgObj.Result})
1538 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1539 return fmt.Errorf("omci CreateResponse Error for device-id %x",
1540 oFsm.deviceID)
1541 }
1542 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1543 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1544 // to satisfy StaticCodeAnalysis I had to move the small processing into a separate method :-(
1545 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001546 case "VlanTaggingFilterData", "MulticastOperationsProfile",
1547 "MulticastSubscriberConfigInfo", "MacBridgePortConfigurationData",
1548 "ExtendedVlanTaggingOperationConfigurationData":
mpagenko01e726e2020-10-23 09:45:29 +00001549 {
1550 if oFsm.pAdaptFsm.pFsm.Current() == vlanStConfigVtfd {
1551 // Only if CreateResponse is received from first flow entry - let the FSM proceed ...
1552 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigVtfd)
1553 } else { // let the MultiEntity config proceed by stopping the wait function
1554 oFsm.omciMIdsResponseReceived <- true
1555 }
1556 }
1557 }
1558 }
1559 return nil
1560}
1561
dbainbri4d3a0dc2020-12-02 00:33:42 +00001562func (oFsm *UniVlanConfigFsm) handleOmciDeleteResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00001563 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeDeleteResponse)
1564 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001565 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001566 log.Fields{"device-id": oFsm.deviceID})
1567 return fmt.Errorf("omci msg layer could not be detected for DeleteResponse for device-id %x",
1568 oFsm.deviceID)
1569 }
1570 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
1571 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001572 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001573 log.Fields{"device-id": oFsm.deviceID})
1574 return fmt.Errorf("omci msg layer could not be assigned for DeleteResponse for device-id %x",
1575 oFsm.deviceID)
1576 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001577 logger.Debugw(ctx, "UniVlanConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko01e726e2020-10-23 09:45:29 +00001578 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001579 logger.Errorw(ctx, "UniVlanConfigFsm - Omci DeleteResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001580 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1581 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1582 return fmt.Errorf("omci DeleteResponse Error for device-id %x",
1583 oFsm.deviceID)
1584 }
1585 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1586 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1587 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001588 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData":
mpagenko01e726e2020-10-23 09:45:29 +00001589 { // let the MultiEntity config proceed by stopping the wait function
1590 oFsm.omciMIdsResponseReceived <- true
1591 }
1592 }
1593 }
1594 return nil
1595}
1596
dbainbri4d3a0dc2020-12-02 00:33:42 +00001597func (oFsm *UniVlanConfigFsm) performConfigEvtocdEntries(ctx context.Context, aFlowEntryNo uint8) error {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001598 if aFlowEntryNo == 0 {
1599 // EthType set only at first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00001600 // EVTOCD ME is expected to exist at this point already from MIB-Download (with AssociationType/Pointer)
1601 // we need to extend the configuration by EthType definition and, to be sure, downstream 'inverse' mode
dbainbri4d3a0dc2020-12-02 00:33:42 +00001602 logger.Debugw(ctx, "UniVlanConfigFsm Tx Create::EVTOCD", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00001603 "EntitytId": strconv.FormatInt(int64(oFsm.evtocdID), 16),
1604 "i/oEthType": strconv.FormatInt(int64(cDefaultTpid), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001605 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001606 associationType := 2 // default to uniPPTP
1607 if oFsm.pOnuUniPort.portType == uniVEIP {
1608 associationType = 10
1609 }
1610 // Create the EVTOCD ME
mpagenkodff5dda2020-08-28 11:52:01 +00001611 meParams := me.ParamData{
1612 EntityID: oFsm.evtocdID,
1613 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001614 "AssociationType": uint8(associationType),
1615 "AssociatedMePointer": oFsm.pOnuUniPort.entityID,
mpagenkodff5dda2020-08-28 11:52:01 +00001616 },
1617 }
Girish Gowdra0b235842021-03-09 13:06:46 -08001618 meInstance := oFsm.pOmciCC.sendCreateEvtocdVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001619 oFsm.pAdaptFsm.commChan, meParams)
1620 //accept also nil as (error) return value for writing to LastTx
1621 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001622 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001623
1624 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001625 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001626 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001627 logger.Errorw(ctx, "Evtocd create failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001628 log.Fields{"device-id": oFsm.deviceID})
1629 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1630 return fmt.Errorf("evtocd create failed %s, error %s", oFsm.deviceID, err)
1631 }
1632
1633 // Set the EVTOCD ME default params
1634 meParams = me.ParamData{
1635 EntityID: oFsm.evtocdID,
1636 Attributes: me.AttributeValueMap{
1637 "InputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
1638 "OutputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
1639 "DownstreamMode": uint8(cDefaultDownstreamMode),
1640 },
1641 }
Girish Gowdra0b235842021-03-09 13:06:46 -08001642 meInstance = oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001643 oFsm.pAdaptFsm.commChan, meParams)
1644 //accept also nil as (error) return value for writing to LastTx
1645 // - this avoids misinterpretation of new received OMCI messages
1646 oFsm.pLastTxMeInstance = meInstance
1647
1648 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001649 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001650 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001651 logger.Errorw(ctx, "Evtocd set TPID failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001652 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301653 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001654 return fmt.Errorf("evtocd set TPID failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00001655 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001656 } //first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00001657
mpagenko551a4d42020-12-08 18:09:20 +00001658 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001659 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00001660 //transparent transmission required
mpagenko551a4d42020-12-08 18:09:20 +00001661 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001662 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged transparent rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001663 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001664 sliceEvtocdRule := make([]uint8, 16)
1665 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1666 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1667 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1668 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1669 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1670
1671 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1672 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
1673 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1674 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1675 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1676
1677 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1678 0<<cTreatTTROffset| // Do not pop any tags
1679 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1680 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1681 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1682
1683 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1684 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
1685 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1686 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
1687
1688 meParams := me.ParamData{
1689 EntityID: oFsm.evtocdID,
1690 Attributes: me.AttributeValueMap{
1691 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1692 },
1693 }
Girish Gowdra0b235842021-03-09 13:06:46 -08001694 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001695 oFsm.pAdaptFsm.commChan, meParams)
1696 //accept also nil as (error) return value for writing to LastTx
1697 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001698 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001699
1700 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001701 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001702 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001703 logger.Errorw(ctx, "Evtocd set transparent singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001704 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301705 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001706 return fmt.Errorf("evtocd set transparent singletagged rule failed %s, error %s", oFsm.deviceID, err)
1707
mpagenkodff5dda2020-08-28 11:52:01 +00001708 }
1709 } else {
1710 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
1711 if oFsm.acceptIncrementalEvtoOption {
mpagenko9a304ea2020-12-16 15:54:01 +00001712 matchPcp := oFsm.actualUniVlanConfigRule.MatchPcp
1713 matchVid := oFsm.actualUniVlanConfigRule.MatchVid
1714 setPcp := oFsm.actualUniVlanConfigRule.SetPcp
1715 setVid := oFsm.actualUniVlanConfigRule.SetVid
mpagenkodff5dda2020-08-28 11:52:01 +00001716 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001717 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged translation rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001718 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001719 sliceEvtocdRule := make([]uint8, 16)
1720 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1721 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1722 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1723 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1724 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1725
1726 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00001727 oFsm.actualUniVlanConfigRule.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
1728 oFsm.actualUniVlanConfigRule.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
mpagenkodff5dda2020-08-28 11:52:01 +00001729 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1730 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1731
1732 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00001733 oFsm.actualUniVlanConfigRule.TagsToRemove<<cTreatTTROffset| // either 1 or 0
mpagenkodff5dda2020-08-28 11:52:01 +00001734 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1735 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1736 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1737
1738 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00001739 oFsm.actualUniVlanConfigRule.SetPcp<<cTreatPrioOffset| // as configured in flow
1740 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| //as configured in flow
mpagenkodff5dda2020-08-28 11:52:01 +00001741 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00001742 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001743
1744 meParams := me.ParamData{
1745 EntityID: oFsm.evtocdID,
1746 Attributes: me.AttributeValueMap{
1747 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1748 },
1749 }
Girish Gowdra0b235842021-03-09 13:06:46 -08001750 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001751 oFsm.pAdaptFsm.commChan, meParams)
1752 //accept also nil as (error) return value for writing to LastTx
1753 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001754 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001755
1756 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001757 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001758 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001759 logger.Errorw(ctx, "Evtocd set singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001760 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301761 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001762 return fmt.Errorf("evtocd set singletagged translation rule failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00001763 }
1764 } else {
1765 //not transparent and not acceptIncrementalEvtoOption untagged/priotagged->singletagged
1766 { // just for local var's
1767 // this defines stacking scenario: untagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00001768 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD untagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001769 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001770 sliceEvtocdRule := make([]uint8, 16)
1771 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1772 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1773 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1774 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1775 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1776
1777 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1778 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
1779 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1780 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1781 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1782
1783 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1784 0<<cTreatTTROffset| // Do not pop any tags
1785 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1786 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1787 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1788
1789 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1790 0<<cTreatPrioOffset| // vlan prio set to 0
1791 // (as done in Py code, maybe better option would be setPcp here, which still could be 0?)
mpagenko9a304ea2020-12-16 15:54:01 +00001792 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| // Outer VID don't care
mpagenkodff5dda2020-08-28 11:52:01 +00001793 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
1794
mpagenko551a4d42020-12-08 18:09:20 +00001795 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001796 meParams := me.ParamData{
1797 EntityID: oFsm.evtocdID,
1798 Attributes: me.AttributeValueMap{
1799 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1800 },
1801 }
Girish Gowdra0b235842021-03-09 13:06:46 -08001802 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001803 oFsm.pAdaptFsm.commChan, meParams)
1804 //accept also nil as (error) return value for writing to LastTx
1805 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001806 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001807
1808 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001809 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001810 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001811 logger.Errorw(ctx, "Evtocd set untagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001812 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301813 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001814 return fmt.Errorf("evtocd set untagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
1815
mpagenkodff5dda2020-08-28 11:52:01 +00001816 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001817 } // just for local var's
mpagenkodff5dda2020-08-28 11:52:01 +00001818 { // just for local var's
1819 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00001820 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD priotagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001821 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001822 sliceEvtocdRule := make([]uint8, 16)
1823 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1824 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1825 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1826 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1827 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1828
1829 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1830 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
1831 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
1832 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1833 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1834
1835 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1836 1<<cTreatTTROffset| // pop the prio-tag
1837 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1838 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1839 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1840
mpagenko551a4d42020-12-08 18:09:20 +00001841 oFsm.mutexFlowParams.RLock()
mpagenkodff5dda2020-08-28 11:52:01 +00001842 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1843 cCopyPrioFromInner<<cTreatPrioOffset| // vlan copy from PrioTag
1844 // (as done in Py code, maybe better option would be setPcp here, which still could be PrioCopy?)
mpagenko9a304ea2020-12-16 15:54:01 +00001845 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| // Outer VID as configured
mpagenkodff5dda2020-08-28 11:52:01 +00001846 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00001847 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001848
1849 meParams := me.ParamData{
1850 EntityID: oFsm.evtocdID,
1851 Attributes: me.AttributeValueMap{
1852 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1853 },
1854 }
Girish Gowdra0b235842021-03-09 13:06:46 -08001855 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001856 oFsm.pAdaptFsm.commChan, meParams)
1857 //accept also nil as (error) return value for writing to LastTx
1858 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001859 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001860
1861 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001862 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001863 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001864 logger.Errorw(ctx, "Evtocd set priotagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001865 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301866 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001867 return fmt.Errorf("evtocd set priotagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
1868
mpagenkodff5dda2020-08-28 11:52:01 +00001869 }
1870 } //just for local var's
1871 }
1872 }
1873
mpagenkofc4f56e2020-11-04 17:17:49 +00001874 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001875 logger.Debugw(ctx, "EVTOCD set loop finished", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001876 oFsm.configuredUniFlow++ // one (more) flow configured
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001877 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00001878}
1879
dbainbri4d3a0dc2020-12-02 00:33:42 +00001880func (oFsm *UniVlanConfigFsm) removeEvtocdEntries(ctx context.Context, aRuleParams uniVlanRuleParams) {
mpagenko01e726e2020-10-23 09:45:29 +00001881 // configured Input/Output TPID is not modified again - no influence if no filter is applied
1882 if aRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
1883 //transparent transmission was set
1884 //perhaps the config is not needed for removal,
1885 // but the specific InnerTpid setting is removed in favor of the real default forwarding rule
dbainbri4d3a0dc2020-12-02 00:33:42 +00001886 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset to default single tagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001887 "device-id": oFsm.deviceID})
1888 sliceEvtocdRule := make([]uint8, 16)
1889 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1890 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1891 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1892 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1893 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1894
1895 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1896 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
1897 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1898 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1899 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1900
1901 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1902 0<<cTreatTTROffset| // Do not pop any tags
1903 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1904 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1905 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1906
1907 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1908 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
1909 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1910 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
1911
1912 meParams := me.ParamData{
1913 EntityID: oFsm.evtocdID,
1914 Attributes: me.AttributeValueMap{
1915 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1916 },
1917 }
Girish Gowdra0b235842021-03-09 13:06:46 -08001918 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00001919 oFsm.pAdaptFsm.commChan, meParams)
1920 //accept also nil as (error) return value for writing to LastTx
1921 // - this avoids misinterpretation of new received OMCI messages
1922 oFsm.pLastTxMeInstance = meInstance
1923
1924 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001925 err := oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001926 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001927 logger.Errorw(ctx, "Evtocd reset singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001928 log.Fields{"device-id": oFsm.deviceID})
1929 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1930 return
1931 }
1932 } else {
1933 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
1934 if oFsm.acceptIncrementalEvtoOption {
1935 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001936 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear single tagged translation rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001937 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
1938 sliceEvtocdRule := make([]uint8, 16)
1939 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1940 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1941 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1942 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1943 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1944
1945 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1946 aRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
1947 aRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
1948 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1949 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1950
1951 // delete indication for the indicated Filter
1952 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
1953 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
1954
1955 meParams := me.ParamData{
1956 EntityID: oFsm.evtocdID,
1957 Attributes: me.AttributeValueMap{
1958 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1959 },
1960 }
Girish Gowdra0b235842021-03-09 13:06:46 -08001961 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00001962 oFsm.pAdaptFsm.commChan, meParams)
1963 //accept also nil as (error) return value for writing to LastTx
1964 // - this avoids misinterpretation of new received OMCI messages
1965 oFsm.pLastTxMeInstance = meInstance
1966
1967 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001968 err := oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001969 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001970 logger.Errorw(ctx, "Evtocd clear singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001971 log.Fields{"device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
1972 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1973 return
1974 }
1975 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001976 // VOL-3685
1977 // NOTE: With ALPHA ONUs it was seen that just resetting a particular entry in the EVTOCD table
1978 // and re-configuring a new entry would not work. The old entry is removed and new entry is created
1979 // indeed, but the traffic landing upstream would carry old vlan sometimes.
1980 // This is only a WORKAROUND which basically deletes the entire EVTOCD ME and re-creates it again
1981 // later when the flow is being re-installed.
1982 // Of course this is applicable to case only where single service (or single tcont) is in use and
1983 // there is only one service vlan (oFsm.acceptIncrementalEvtoOption is false in this case).
1984 // Interstingly this problem has not been observed in multi-tcont (or multi-service) scenario (in
1985 // which case the oFsm.acceptIncrementalEvtoOption is set to true).
1986 if oFsm.configuredUniFlow == 0 && !oFsm.acceptIncrementalEvtoOption {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001987 logger.Debugw(ctx, "UniVlanConfigFsm Tx Remove::EVTOCD", log.Fields{"device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001988 // When there are no more EVTOCD vlan configurations on the ONU and acceptIncrementalEvtoOption
1989 // is not enabled, delete the EVTOCD ME.
mpagenko01e726e2020-10-23 09:45:29 +00001990 meParams := me.ParamData{
1991 EntityID: oFsm.evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00001992 }
Girish Gowdra0b235842021-03-09 13:06:46 -08001993 meInstance := oFsm.pOmciCC.sendDeleteEvtocd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00001994 oFsm.pAdaptFsm.commChan, meParams)
1995 //accept also nil as (error) return value for writing to LastTx
1996 // - this avoids misinterpretation of new received OMCI messages
1997 oFsm.pLastTxMeInstance = meInstance
1998
1999 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002000 err := oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002001 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002002 logger.Errorw(ctx, "Evtocd delete rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002003 log.Fields{"device-id": oFsm.deviceID})
2004 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2005 return
2006 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002007 } else {
2008 // NOTE : We should ideally never ether this section when oFsm.acceptIncrementalEvtoOption is set to false
2009 // This is true for only ATT/DT workflow
dbainbri4d3a0dc2020-12-02 00:33:42 +00002010 logger.Debugw(ctx, "UniVlanConfigFsm: Remove EVTOCD set operation",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002011 log.Fields{"configured-flow": oFsm.configuredUniFlow, "incremental-evto": oFsm.acceptIncrementalEvtoOption})
2012 //not transparent and not acceptIncrementalEvtoOption: untagged/priotagged->singletagged
2013 { // just for local var's
2014 // this defines stacking scenario: untagged->singletagged
2015 //TODO!! in theory there could be different rules running in setting different PCP/VID'S
2016 // for untagged/priotagged, last rule wins (and remains the only one), maybe that should be
2017 // checked already at flow-add (and rejected) - to be observed if such is possible in Voltha
2018 // delete now assumes there is only one such rule!
dbainbri4d3a0dc2020-12-02 00:33:42 +00002019 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset untagged rule to default", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002020 "device-id": oFsm.deviceID})
2021 sliceEvtocdRule := make([]uint8, 16)
2022 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2023 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2024 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2025 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2026 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00002027
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002028 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2029 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2030 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2031 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2032 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00002033
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002034 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2035 0<<cTreatTTROffset| // Do not pop any tags
2036 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2037 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2038 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
mpagenko01e726e2020-10-23 09:45:29 +00002039
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002040 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2041 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2042 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2043 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
mpagenko01e726e2020-10-23 09:45:29 +00002044
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002045 meParams := me.ParamData{
2046 EntityID: oFsm.evtocdID,
2047 Attributes: me.AttributeValueMap{
2048 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2049 },
2050 }
Girish Gowdra0b235842021-03-09 13:06:46 -08002051 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002052 oFsm.pAdaptFsm.commChan, meParams)
2053 //accept also nil as (error) return value for writing to LastTx
2054 // - this avoids misinterpretation of new received OMCI messages
2055 oFsm.pLastTxMeInstance = meInstance
2056
2057 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002058 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002059 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002060 logger.Errorw(ctx, "Evtocd reset untagged rule to default failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002061 log.Fields{"device-id": oFsm.deviceID})
2062 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2063 return
2064 }
2065 } // just for local var's
2066 { // just for local var's
2067 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002068 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD delete priotagged rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002069 "device-id": oFsm.deviceID})
2070 sliceEvtocdRule := make([]uint8, 16)
2071 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2072 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2073 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2074 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2075 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2076
2077 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2078 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2079 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2080 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2081 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2082
2083 // delete indication for the indicated Filter
2084 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2085 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2086
2087 meParams := me.ParamData{
2088 EntityID: oFsm.evtocdID,
2089 Attributes: me.AttributeValueMap{
2090 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2091 },
2092 }
Girish Gowdra0b235842021-03-09 13:06:46 -08002093 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002094 oFsm.pAdaptFsm.commChan, meParams)
2095 //accept also nil as (error) return value for writing to LastTx
2096 // - this avoids misinterpretation of new received OMCI messages
2097 oFsm.pLastTxMeInstance = meInstance
2098
2099 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002100 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002101 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002102 logger.Errorw(ctx, "Evtocd delete priotagged rule failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002103 log.Fields{"device-id": oFsm.deviceID})
2104 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2105 return
2106 }
mpagenko01e726e2020-10-23 09:45:29 +00002107 }
2108 } //just for local var's
2109 }
2110 }
2111
mpagenkofc4f56e2020-11-04 17:17:49 +00002112 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002113 logger.Debugw(ctx, "EVTOCD filter remove loop finished", log.Fields{"device-id": oFsm.deviceID})
Girish Gowdra26a40922021-01-29 17:14:34 -08002114 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRemFlowDone, aRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00002115}
2116
dbainbri4d3a0dc2020-12-02 00:33:42 +00002117func (oFsm *UniVlanConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00002118 oFsm.mutexIsAwaitingResponse.Lock()
2119 oFsm.isAwaitingResponse = true
2120 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002121 select {
Himani Chawla26e555c2020-08-31 12:30:20 +05302122 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenkodff5dda2020-08-28 11:52:01 +00002123 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00002124 // logger.Infow(ctx,"LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002125 case <-time.After(30 * time.Second): //AS FOR THE OTHER OMCI FSM's
dbainbri4d3a0dc2020-12-02 00:33:42 +00002126 logger.Warnw(ctx, "UniVlanConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002127 oFsm.mutexIsAwaitingResponse.Lock()
2128 oFsm.isAwaitingResponse = false
2129 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002130 return fmt.Errorf("uniVlanConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002131 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05302132 if success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002133 logger.Debug(ctx, "UniVlanConfigFsm multi entity response received")
mpagenko7d6bb022021-03-11 15:07:55 +00002134 oFsm.mutexIsAwaitingResponse.Lock()
2135 oFsm.isAwaitingResponse = false
2136 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002137 return nil
2138 }
mpagenko7d6bb022021-03-11 15:07:55 +00002139 // waiting was aborted (probably on external request)
2140 logger.Debugw(ctx, "UniVlanConfigFsm wait for multi entity response aborted", log.Fields{"for device-id": oFsm.deviceID})
2141 oFsm.mutexIsAwaitingResponse.Lock()
2142 oFsm.isAwaitingResponse = false
2143 oFsm.mutexIsAwaitingResponse.Unlock()
2144 return fmt.Errorf(cErrWaitAborted)
mpagenkodff5dda2020-08-28 11:52:01 +00002145 }
2146}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002147
mpagenko551a4d42020-12-08 18:09:20 +00002148func (oFsm *UniVlanConfigFsm) performSettingMulticastME(ctx context.Context, tpID uint8, multicastGemPortID uint16, vlanID uint32) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002149 logger.Debugw(ctx, "Setting Multicast MEs", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002150 "multicastGemPortID": multicastGemPortID, "vlanID": vlanID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002151 errCreateMOP := oFsm.performCreatingMulticastOperationProfile(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002152 if errCreateMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002153 logger.Errorw(ctx, "MulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002154 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002155 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002156 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMOP)
2157 }
2158
dbainbri4d3a0dc2020-12-02 00:33:42 +00002159 errSettingMOP := oFsm.performSettingMulticastOperationProfile(ctx, multicastGemPortID, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002160 if errSettingMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002161 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002162 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002163 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002164 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errSettingMOP)
2165 }
2166
dbainbri4d3a0dc2020-12-02 00:33:42 +00002167 errCreateMSCI := oFsm.performCreatingMulticastSubscriberConfigInfo(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002168 if errCreateMSCI != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002169 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002170 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002171 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002172 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMSCI)
2173 }
2174
2175 meParams := me.ParamData{
2176 EntityID: macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo),
2177 Attributes: me.AttributeValueMap{
2178 "BridgeIdPointer": macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo),
2179 "PortNum": 0xf0, //fixed unique ANI side indication
2180 "TpType": 6, //MCGemIWTP
2181 "TpPointer": multicastGemPortID,
2182 },
2183 }
Girish Gowdra0b235842021-03-09 13:06:46 -08002184 meInstance := oFsm.pOmciCC.sendCreateMBPConfigDataVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002185 oFsm.pAdaptFsm.commChan, meParams)
2186 //accept also nil as (error) return value for writing to LastTx
2187 // - this avoids misinterpretation of new received OMCI messages
2188 oFsm.pLastTxMeInstance = meInstance
dbainbri4d3a0dc2020-12-02 00:33:42 +00002189 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002190 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002191 logger.Errorw(ctx, "CreateMBPConfigData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002192 log.Fields{"device-id": oFsm.deviceID, "MBPConfigDataID": macBridgeServiceProfileEID})
mpagenko9a304ea2020-12-16 15:54:01 +00002193 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002194 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, err)
2195 }
2196
2197 // ==> Start creating VTFD for mcast vlan
2198
2199 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
2200 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
2201 mcastVtfdID := macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo)
2202
dbainbri4d3a0dc2020-12-02 00:33:42 +00002203 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD for mcast", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002204 "EntitytId": strconv.FormatInt(int64(mcastVtfdID), 16), "mcastVlanID": vlanID,
2205 "in state": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
2206 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
2207
2208 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
2209 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
2210 // new vlan associated with a different TP.
2211 vtfdFilterList[0] = uint16(vlanID)
2212
2213 meParams = me.ParamData{
2214 EntityID: mcastVtfdID,
2215 Attributes: me.AttributeValueMap{
2216 "VlanFilterList": vtfdFilterList,
2217 "ForwardOperation": uint8(0x10), //VID investigation
2218 "NumberOfEntries": oFsm.numVlanFilterEntries,
2219 },
2220 }
Girish Gowdra0b235842021-03-09 13:06:46 -08002221 meInstance = oFsm.pOmciCC.sendCreateVtfdVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002222 oFsm.pAdaptFsm.commChan, meParams)
2223 oFsm.pLastTxMeInstance = meInstance
dbainbri4d3a0dc2020-12-02 00:33:42 +00002224 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002225 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002226 logger.Errorw(ctx, "CreateMcastVlanFilterData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002227 log.Fields{"device-id": oFsm.deviceID, "mcastVtfdID": mcastVtfdID})
mpagenko9a304ea2020-12-16 15:54:01 +00002228 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002229 return fmt.Errorf("createMcastVlanFilterData responseError %s, error %s", oFsm.deviceID, err)
2230 }
2231
2232 return nil
2233}
2234
dbainbri4d3a0dc2020-12-02 00:33:42 +00002235func (oFsm *UniVlanConfigFsm) performCreatingMulticastSubscriberConfigInfo(ctx context.Context) error {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002236 instID, err := oFsm.pDeviceHandler.getUniPortMEEntityID(oFsm.pOnuUniPort.portNo)
2237 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002238 logger.Errorw(ctx, "error fetching uni port me instance",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002239 log.Fields{"device-id": oFsm.deviceID, "portNo": oFsm.pOnuUniPort.portNo})
2240 return err
2241 }
ozgecanetsia5c88b762021-03-23 10:27:15 +03002242 instID += macBridgePortAniEID
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002243 meParams := me.ParamData{
2244 EntityID: instID,
2245 Attributes: me.AttributeValueMap{
2246 "MeType": 0,
2247 //Direct reference to the Operation profile
2248 //TODO ANI side used on UNI side, not the clearest option.
ozgecanetsia5c88b762021-03-23 10:27:15 +03002249 "MulticastOperationsProfilePointer": instID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002250 },
2251 }
Girish Gowdra0b235842021-03-09 13:06:46 -08002252 meInstance := oFsm.pOmciCC.sendCreateMulticastSubConfigInfoVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002253 oFsm.pAdaptFsm.commChan, meParams)
2254 //accept also nil as (error) return value for writing to LastTx
2255 // - this avoids misinterpretation of new received OMCI messages
2256 oFsm.pLastTxMeInstance = meInstance
2257 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002258 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002259 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002260 logger.Errorw(ctx, "CreateMulticastSubConfigInfo create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002261 log.Fields{"device-id": oFsm.deviceID, "MulticastSubConfigInfo": instID})
2262 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s", oFsm.deviceID)
2263 }
2264 return nil
2265}
2266
dbainbri4d3a0dc2020-12-02 00:33:42 +00002267func (oFsm *UniVlanConfigFsm) performCreatingMulticastOperationProfile(ctx context.Context) error {
ozgecanetsia5c88b762021-03-23 10:27:15 +03002268 instID, err := oFsm.pDeviceHandler.getUniPortMEEntityID(oFsm.pOnuUniPort.portNo)
2269 if err != nil {
2270 logger.Errorw(ctx, "error fetching uni port me instance",
2271 log.Fields{"device-id": oFsm.deviceID, "portNo": oFsm.pOnuUniPort.portNo})
2272 return err
2273 }
2274 instID += macBridgePortAniEID
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002275 meParams := me.ParamData{
2276 EntityID: instID,
2277 Attributes: me.AttributeValueMap{
2278 "IgmpVersion": 2,
2279 "IgmpFunction": 0,
2280 //0 means false
2281 "ImmediateLeave": 0,
2282 "Robustness": 2,
2283 "QuerierIp": 0,
2284 "QueryInterval": 125,
2285 "QuerierMaxResponseTime": 100,
2286 "LastMemberResponseTime": 10,
2287 //0 means false
2288 "UnauthorizedJoinBehaviour": 0,
2289 },
2290 }
Girish Gowdra0b235842021-03-09 13:06:46 -08002291 meInstance := oFsm.pOmciCC.sendCreateMulticastOperationProfileVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002292 oFsm.pAdaptFsm.commChan, meParams)
2293 //accept also nil as (error) return value for writing to LastTx
2294 // - this avoids misinterpretation of new received OMCI messages
2295 oFsm.pLastTxMeInstance = meInstance
2296 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03002297 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002298 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002299 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002300 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
2301 return fmt.Errorf("createMulticastOperationProfile responseError %s", oFsm.deviceID)
2302 }
2303 return nil
2304}
2305
dbainbri4d3a0dc2020-12-02 00:33:42 +00002306func (oFsm *UniVlanConfigFsm) performSettingMulticastOperationProfile(ctx context.Context, multicastGemPortID uint16, vlanID uint32) error {
ozgecanetsia5c88b762021-03-23 10:27:15 +03002307 instID, err := oFsm.pDeviceHandler.getUniPortMEEntityID(oFsm.pOnuUniPort.portNo)
2308 if err != nil {
2309 logger.Errorw(ctx, "error fetching uni port me instance",
2310 log.Fields{"device-id": oFsm.deviceID, "portNo": oFsm.pOnuUniPort.portNo})
2311 return err
2312 }
2313 instID += macBridgePortAniEID
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002314 //TODO check that this is correct
2315 // Table control
2316 //setCtrl = 1
2317 //rowPartId = 0
2318 //test = 0
2319 //rowKey = 0
2320 tableCtrlStr := "0100000000000000"
2321 tableCtrl := AsByteSlice(tableCtrlStr)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002322 dynamicAccessCL := make([]uint8, 24)
2323 copy(dynamicAccessCL, tableCtrl)
2324 //Multicast GemPortId
2325 binary.BigEndian.PutUint16(dynamicAccessCL[2:], multicastGemPortID)
2326 // python version waits for installation of flows, see line 723 onward of
2327 // brcm_openomci_onu_handler.py
2328 binary.BigEndian.PutUint16(dynamicAccessCL[4:], uint16(vlanID))
2329 //Source IP all to 0
2330 binary.BigEndian.PutUint32(dynamicAccessCL[6:], IPToInt32(net.IPv4(0, 0, 0, 0)))
2331 //TODO start and end are hardcoded, get from TP
2332 // Destination IP address start of range
2333 binary.BigEndian.PutUint32(dynamicAccessCL[10:], IPToInt32(net.IPv4(225, 0, 0, 0)))
2334 // Destination IP address end of range
2335 binary.BigEndian.PutUint32(dynamicAccessCL[14:], IPToInt32(net.IPv4(239, 255, 255, 255)))
2336 //imputed group bandwidth
2337 binary.BigEndian.PutUint16(dynamicAccessCL[18:], 0)
2338
2339 meParams := me.ParamData{
2340 EntityID: instID,
2341 Attributes: me.AttributeValueMap{
2342 "DynamicAccessControlListTable": dynamicAccessCL,
2343 },
2344 }
Girish Gowdra0b235842021-03-09 13:06:46 -08002345 meInstance := oFsm.pOmciCC.sendSetMulticastOperationProfileVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002346 oFsm.pAdaptFsm.commChan, meParams)
2347 //accept also nil as (error) return value for writing to LastTx
2348 // - this avoids misinterpretation of new received OMCI messages
2349 oFsm.pLastTxMeInstance = meInstance
2350 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03002351 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002352 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002353 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002354 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
2355 return fmt.Errorf("createMulticastOperationProfile responseError %s", oFsm.deviceID)
2356 }
2357 return nil
2358}
Girish Gowdra26a40922021-01-29 17:14:34 -08002359
2360// IsFlowRemovePending returns true if there are pending flows to remove, else false.
2361func (oFsm *UniVlanConfigFsm) IsFlowRemovePending() bool {
2362 oFsm.mutexFlowParams.RLock()
2363 defer oFsm.mutexFlowParams.RUnlock()
2364 return len(oFsm.uniRemoveFlowsSlice) > 0
2365}