blob: befc4a28511921dee00445989f881ec0af135274 [file] [log] [blame]
mpagenkodff5dda2020-08-28 11:52:01 +00001/*
2 * Copyright 2020-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//Package adaptercoreonu provides the utility for onu devices, flows and statistics
18package adaptercoreonu
19
20import (
21 "context"
22 "encoding/binary"
Andrea Campanella6515c582020-10-05 11:25:00 +020023 "fmt"
ozgecanetsiab5000ef2020-11-27 14:38:20 +030024 "net"
mpagenkodff5dda2020-08-28 11:52:01 +000025 "strconv"
Holger Hildebrandt394c5522020-09-11 11:23:01 +000026 "sync"
mpagenkodff5dda2020-08-28 11:52:01 +000027 "time"
28
mpagenko01e726e2020-10-23 09:45:29 +000029 gp "github.com/google/gopacket"
mpagenkodff5dda2020-08-28 11:52:01 +000030 "github.com/looplab/fsm"
31 "github.com/opencord/omci-lib-go"
32 me "github.com/opencord/omci-lib-go/generated"
dbainbri4d3a0dc2020-12-02 00:33:42 +000033 "github.com/opencord/voltha-lib-go/v4/pkg/log"
34 of "github.com/opencord/voltha-protos/v4/go/openflow_13"
mpagenkodff5dda2020-08-28 11:52:01 +000035)
36
37const (
38 // internal predefined values
39 cDefaultDownstreamMode = 0
40 cDefaultTpid = 0x8100
mpagenko01e726e2020-10-23 09:45:29 +000041 cVtfdTableSize = 12 //as per G.988
42 cMaxAllowedFlows = cVtfdTableSize //which might be under discussion, for the moment connected to limit of VLAN's within VTFD
mpagenkodff5dda2020-08-28 11:52:01 +000043)
44
45const (
46 // bit mask offsets for EVTOCD VlanTaggingOperationTable related to 32 bits (4 bytes)
47 cFilterPrioOffset = 28
48 cFilterVidOffset = 15
49 cFilterTpidOffset = 12
50 cFilterEtherTypeOffset = 0
51 cTreatTTROffset = 30
52 cTreatPrioOffset = 16
53 cTreatVidOffset = 3
54 cTreatTpidOffset = 0
55)
56const (
57 // byte offsets for EVTOCD VlanTaggingOperationTable related to overall 16 byte size with slice byte 0 as first Byte (MSB)
58 cFilterOuterOffset = 0
59 cFilterInnerOffset = 4
60 cTreatOuterOffset = 8
61 cTreatInnerOffset = 12
62)
63const (
64 // basic values used within EVTOCD VlanTaggingOperationTable in respect to their bitfields
65 cPrioIgnoreTag uint32 = 15
66 cPrioDefaultFilter uint32 = 14
67 cPrioDoNotFilter uint32 = 8
68 cDoNotFilterVid uint32 = 4096
69 cDoNotFilterTPID uint32 = 0
70 cDoNotFilterEtherType uint32 = 0
71 cDoNotAddPrio uint32 = 15
72 cCopyPrioFromInner uint32 = 8
Himani Chawla4d908332020-08-31 12:30:20 +053073 //cDontCarePrio uint32 = 0
mpagenkodff5dda2020-08-28 11:52:01 +000074 cDontCareVid uint32 = 0
75 cDontCareTpid uint32 = 0
76 cSetOutputTpidCopyDei uint32 = 4
77)
78
79const (
80 // events of config PON ANI port FSM
mpagenko01e726e2020-10-23 09:45:29 +000081 vlanEvStart = "vlanEvStart"
82 vlanEvWaitTechProf = "vlanEvWaitTechProf"
83 vlanEvContinueConfig = "vlanEvContinueConfig"
84 vlanEvStartConfig = "vlanEvStartConfig"
85 vlanEvRxConfigVtfd = "vlanEvRxConfigVtfd"
86 vlanEvRxConfigEvtocd = "vlanEvRxConfigEvtocd"
mpagenko551a4d42020-12-08 18:09:20 +000087 vlanEvWaitTPIncr = "vlanEvWaitTPIncr"
mpagenko01e726e2020-10-23 09:45:29 +000088 vlanEvIncrFlowConfig = "vlanEvIncrFlowConfig"
mpagenkofc4f56e2020-11-04 17:17:49 +000089 vlanEvRenew = "vlanEvRenew"
mpagenko01e726e2020-10-23 09:45:29 +000090 vlanEvRemFlowConfig = "vlanEvRemFlowConfig"
91 vlanEvRemFlowDone = "vlanEvRemFlowDone"
92 vlanEvFlowDataRemoved = "vlanEvFlowDataRemoved"
Holger Hildebrandt394c5522020-09-11 11:23:01 +000093 //vlanEvTimeoutSimple = "vlanEvTimeoutSimple"
94 //vlanEvTimeoutMids = "vlanEvTimeoutMids"
Himani Chawla4d908332020-08-31 12:30:20 +053095 vlanEvReset = "vlanEvReset"
96 vlanEvRestart = "vlanEvRestart"
mpagenkodff5dda2020-08-28 11:52:01 +000097)
mpagenko01e726e2020-10-23 09:45:29 +000098
mpagenkodff5dda2020-08-28 11:52:01 +000099const (
100 // states of config PON ANI port FSM
101 vlanStDisabled = "vlanStDisabled"
102 vlanStStarting = "vlanStStarting"
103 vlanStWaitingTechProf = "vlanStWaitingTechProf"
104 vlanStConfigVtfd = "vlanStConfigVtfd"
105 vlanStConfigEvtocd = "vlanStConfigEvtocd"
106 vlanStConfigDone = "vlanStConfigDone"
mpagenko551a4d42020-12-08 18:09:20 +0000107 vlanStIncrFlowWaitTP = "vlanStIncrFlowWaitTP"
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000108 vlanStConfigIncrFlow = "vlanStConfigIncrFlow"
mpagenko01e726e2020-10-23 09:45:29 +0000109 vlanStRemoveFlow = "vlanStRemoveFlow"
mpagenkodff5dda2020-08-28 11:52:01 +0000110 vlanStCleanupDone = "vlanStCleanupDone"
111 vlanStResetting = "vlanStResetting"
112)
113
mpagenko01e726e2020-10-23 09:45:29 +0000114type uniVlanRuleParams struct {
mpagenko551a4d42020-12-08 18:09:20 +0000115 TpID uint8 `json:"tp_id"`
mpagenko01e726e2020-10-23 09:45:29 +0000116 MatchVid uint32 `json:"match_vid"` //use uint32 types for allowing immediate bitshifting
117 MatchPcp uint32 `json:"match_pcp"`
118 TagsToRemove uint32 `json:"tags_to_remove"`
119 SetVid uint32 `json:"set_vid"`
120 SetPcp uint32 `json:"set_pcp"`
121}
122
123type uniVlanFlowParams struct {
124 CookieSlice []uint64 `json:"cookie_slice"`
125 VlanRuleParams uniVlanRuleParams `json:"vlan_rule_params"`
126}
127
128type uniRemoveVlanFlowParams struct {
129 cookie uint64 //just the last cookie valid for removal
130 vlanRuleParams uniVlanRuleParams
131}
132
mpagenkodff5dda2020-08-28 11:52:01 +0000133//UniVlanConfigFsm defines the structure for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
134type UniVlanConfigFsm struct {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530135 pDeviceHandler *deviceHandler
mpagenko01e726e2020-10-23 09:45:29 +0000136 deviceID string
Himani Chawla6d2ae152020-09-02 13:11:20 +0530137 pOmciCC *omciCC
138 pOnuUniPort *onuUniPort
139 pUniTechProf *onuUniTechProf
140 pOnuDB *onuDeviceDB
mpagenkodff5dda2020-08-28 11:52:01 +0000141 requestEvent OnuDeviceEvent
142 omciMIdsResponseReceived chan bool //seperate channel needed for checking multiInstance OMCI message responses
143 pAdaptFsm *AdapterFsm
144 acceptIncrementalEvtoOption bool
mpagenko2418ab02020-11-12 12:58:06 +0000145 clearPersistency bool
mpagenko551a4d42020-12-08 18:09:20 +0000146 mutexFlowParams sync.RWMutex
mpagenko01e726e2020-10-23 09:45:29 +0000147 uniVlanFlowParamsSlice []uniVlanFlowParams
148 uniRemoveFlowsSlice []uniRemoveVlanFlowParams
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000149 numUniFlows uint8 // expected number of flows should be less than 12
150 configuredUniFlow uint8
mpagenko01e726e2020-10-23 09:45:29 +0000151 numRemoveFlows uint8
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000152 numVlanFilterEntries uint8
mpagenko01e726e2020-10-23 09:45:29 +0000153 vlanFilterList [cVtfdTableSize]uint16
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000154 evtocdID uint16
mpagenko01e726e2020-10-23 09:45:29 +0000155 pLastTxMeInstance *me.ManagedEntity
mpagenkofc4f56e2020-11-04 17:17:49 +0000156 requestEventOffset uint8
mpagenko551a4d42020-12-08 18:09:20 +0000157 TpIDWaitingFor uint8
mpagenkodff5dda2020-08-28 11:52:01 +0000158}
159
mpagenko01e726e2020-10-23 09:45:29 +0000160//NewUniVlanConfigFsm is the 'constructor' for the state machine to config the PON ANI ports
161// of ONU UNI ports via OMCI
dbainbri4d3a0dc2020-12-02 00:33:42 +0000162func NewUniVlanConfigFsm(ctx context.Context, apDeviceHandler *deviceHandler, apDevOmciCC *omciCC, apUniPort *onuUniPort,
mpagenko551a4d42020-12-08 18:09:20 +0000163 apUniTechProf *onuUniTechProf, apOnuDB *onuDeviceDB, aTechProfileID uint8,
mpagenko01e726e2020-10-23 09:45:29 +0000164 aRequestEvent OnuDeviceEvent, aName string, aCommChannel chan Message, aAcceptIncrementalEvto bool,
165 aCookieSlice []uint64, aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) *UniVlanConfigFsm {
mpagenkodff5dda2020-08-28 11:52:01 +0000166 instFsm := &UniVlanConfigFsm{
167 pDeviceHandler: apDeviceHandler,
mpagenko01e726e2020-10-23 09:45:29 +0000168 deviceID: apDeviceHandler.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +0000169 pOmciCC: apDevOmciCC,
170 pOnuUniPort: apUniPort,
171 pUniTechProf: apUniTechProf,
172 pOnuDB: apOnuDB,
mpagenkodff5dda2020-08-28 11:52:01 +0000173 requestEvent: aRequestEvent,
174 acceptIncrementalEvtoOption: aAcceptIncrementalEvto,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000175 numUniFlows: 0,
176 configuredUniFlow: 0,
mpagenko01e726e2020-10-23 09:45:29 +0000177 numRemoveFlows: 0,
mpagenko2418ab02020-11-12 12:58:06 +0000178 clearPersistency: true,
mpagenkodff5dda2020-08-28 11:52:01 +0000179 }
180
mpagenko01e726e2020-10-23 09:45:29 +0000181 instFsm.pAdaptFsm = NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
mpagenkodff5dda2020-08-28 11:52:01 +0000182 if instFsm.pAdaptFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000183 logger.Errorw(ctx, "UniVlanConfigFsm's AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000184 "device-id": instFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000185 return nil
186 }
mpagenkodff5dda2020-08-28 11:52:01 +0000187 instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
188 vlanStDisabled,
189 fsm.Events{
190 {Name: vlanEvStart, Src: []string{vlanStDisabled}, Dst: vlanStStarting},
191 {Name: vlanEvWaitTechProf, Src: []string{vlanStStarting}, Dst: vlanStWaitingTechProf},
192 {Name: vlanEvContinueConfig, Src: []string{vlanStWaitingTechProf}, Dst: vlanStConfigVtfd},
193 {Name: vlanEvStartConfig, Src: []string{vlanStStarting}, Dst: vlanStConfigVtfd},
194 {Name: vlanEvRxConfigVtfd, Src: []string{vlanStConfigVtfd}, Dst: vlanStConfigEvtocd},
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000195 {Name: vlanEvRxConfigEvtocd, Src: []string{vlanStConfigEvtocd, vlanStConfigIncrFlow},
196 Dst: vlanStConfigDone},
mpagenko551a4d42020-12-08 18:09:20 +0000197 {Name: vlanEvRenew, Src: []string{vlanStConfigDone}, Dst: vlanStStarting},
198 {Name: vlanEvWaitTPIncr, Src: []string{vlanStConfigDone}, Dst: vlanStIncrFlowWaitTP},
199 {Name: vlanEvIncrFlowConfig, Src: []string{vlanStConfigDone, vlanStIncrFlowWaitTP},
200 Dst: vlanStConfigIncrFlow},
mpagenko01e726e2020-10-23 09:45:29 +0000201 {Name: vlanEvRemFlowConfig, Src: []string{vlanStConfigDone}, Dst: vlanStRemoveFlow},
202 {Name: vlanEvRemFlowDone, Src: []string{vlanStRemoveFlow}, Dst: vlanStCleanupDone},
203 {Name: vlanEvFlowDataRemoved, Src: []string{vlanStCleanupDone}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000204 /*
205 {Name: vlanEvTimeoutSimple, Src: []string{
206 vlanStCreatingDot1PMapper, vlanStCreatingMBPCD, vlanStSettingTconts, vlanStSettingDot1PMapper}, Dst: vlanStStarting},
207 {Name: vlanEvTimeoutMids, Src: []string{
208 vlanStCreatingGemNCTPs, vlanStCreatingGemIWs, vlanStSettingPQs}, Dst: vlanStStarting},
209 */
210 // exceptional treatment for all states except vlanStResetting
211 {Name: vlanEvReset, Src: []string{vlanStStarting, vlanStWaitingTechProf,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000212 vlanStConfigVtfd, vlanStConfigEvtocd, vlanStConfigDone, vlanStConfigIncrFlow,
mpagenko01e726e2020-10-23 09:45:29 +0000213 vlanStRemoveFlow, vlanStCleanupDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000214 Dst: vlanStResetting},
215 // the only way to get to resource-cleared disabled state again is via "resseting"
216 {Name: vlanEvRestart, Src: []string{vlanStResetting}, Dst: vlanStDisabled},
217 },
mpagenkodff5dda2020-08-28 11:52:01 +0000218 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000219 "enter_state": func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(ctx, e) },
220 "enter_" + vlanStStarting: func(e *fsm.Event) { instFsm.enterConfigStarting(ctx, e) },
221 "enter_" + vlanStConfigVtfd: func(e *fsm.Event) { instFsm.enterConfigVtfd(ctx, e) },
222 "enter_" + vlanStConfigEvtocd: func(e *fsm.Event) { instFsm.enterConfigEvtocd(ctx, e) },
223 "enter_" + vlanStConfigDone: func(e *fsm.Event) { instFsm.enterVlanConfigDone(ctx, e) },
224 "enter_" + vlanStConfigIncrFlow: func(e *fsm.Event) { instFsm.enterConfigIncrFlow(ctx, e) },
225 "enter_" + vlanStRemoveFlow: func(e *fsm.Event) { instFsm.enterRemoveFlow(ctx, e) },
226 "enter_" + vlanStCleanupDone: func(e *fsm.Event) { instFsm.enterVlanCleanupDone(ctx, e) },
227 "enter_" + vlanStResetting: func(e *fsm.Event) { instFsm.enterResetting(ctx, e) },
228 "enter_" + vlanStDisabled: func(e *fsm.Event) { instFsm.enterDisabled(ctx, e) },
mpagenkodff5dda2020-08-28 11:52:01 +0000229 },
230 )
231 if instFsm.pAdaptFsm.pFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000232 logger.Errorw(ctx, "UniVlanConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000233 "device-id": instFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000234 return nil
235 }
236
dbainbri4d3a0dc2020-12-02 00:33:42 +0000237 _ = instFsm.initUniFlowParams(ctx, aTechProfileID, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000238
dbainbri4d3a0dc2020-12-02 00:33:42 +0000239 logger.Debugw(ctx, "UniVlanConfigFsm created", log.Fields{"device-id": instFsm.deviceID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000240 "accIncrEvto": instFsm.acceptIncrementalEvtoOption})
mpagenkodff5dda2020-08-28 11:52:01 +0000241 return instFsm
242}
243
mpagenko01e726e2020-10-23 09:45:29 +0000244//initUniFlowParams is a simplified form of SetUniFlowParams() used for first flow parameters configuration
mpagenko551a4d42020-12-08 18:09:20 +0000245func (oFsm *UniVlanConfigFsm) initUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +0000246 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) error {
247 loRuleParams := uniVlanRuleParams{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000248 TpID: aTpID,
249 MatchVid: uint32(aMatchVlan),
250 SetVid: uint32(aSetVlan),
251 SetPcp: uint32(aSetPcp),
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000252 }
253 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
mpagenko01e726e2020-10-23 09:45:29 +0000254 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
255 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000256
mpagenko01e726e2020-10-23 09:45:29 +0000257 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000258 //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 +0000259 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000260 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
261 } else {
262 if !oFsm.acceptIncrementalEvtoOption {
263 //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 +0000264 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000265 }
266 }
267
mpagenko01e726e2020-10-23 09:45:29 +0000268 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000269 // no prio/vid filtering requested
mpagenko01e726e2020-10-23 09:45:29 +0000270 loRuleParams.TagsToRemove = 0 //no tag pop action
271 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
272 if loRuleParams.SetPcp == cCopyPrioFromInner {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000273 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
274 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
275 // might collide with NoMatchVid/CopyPrio(/setVid) setting
276 // this was some precondition setting taken over from py adapter ..
mpagenko01e726e2020-10-23 09:45:29 +0000277 loRuleParams.SetPcp = 0
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000278 }
279 }
mpagenko01e726e2020-10-23 09:45:29 +0000280
281 loFlowParams := uniVlanFlowParams{VlanRuleParams: loRuleParams}
282 loFlowParams.CookieSlice = make([]uint64, 0)
283 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
284
285 //no mutex protection is required for initial access and adding the first flow is always possible
286 oFsm.uniVlanFlowParamsSlice = make([]uniVlanFlowParams, 0)
287 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000288 logger.Debugw(ctx, "first UniVlanConfigFsm flow added", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000289 "Cookies": oFsm.uniVlanFlowParamsSlice[0].CookieSlice,
290 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
291 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
292 "SetPcp": loRuleParams.SetPcp,
293 "device-id": oFsm.deviceID})
294 oFsm.numUniFlows = 1
295 oFsm.uniRemoveFlowsSlice = make([]uniRemoveVlanFlowParams, 0) //initially nothing to remove
296
297 //permanently store flow config for reconcile case
dbainbri4d3a0dc2020-12-02 00:33:42 +0000298 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
mpagenko01e726e2020-10-23 09:45:29 +0000299 &oFsm.uniVlanFlowParamsSlice); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000300 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000301 return err
302 }
303
304 return nil
305}
306
mpagenko551a4d42020-12-08 18:09:20 +0000307//GetWaitingTpID returns the TpId that the FSM might be waiting for continuation (0 if none)
308func (oFsm *UniVlanConfigFsm) GetWaitingTpID() uint8 {
309 //mutex protection is required for possible concurrent access to FSM members
310 oFsm.mutexFlowParams.RLock()
311 defer oFsm.mutexFlowParams.RUnlock()
312 return oFsm.TpIDWaitingFor
313}
314
mpagenko2418ab02020-11-12 12:58:06 +0000315//RequestClearPersistency sets the internal flag to not clear persistency data (false=NoClear)
316func (oFsm *UniVlanConfigFsm) RequestClearPersistency(aClear bool) {
317 //mutex protection is required for possible concurrent access to FSM members
mpagenko551a4d42020-12-08 18:09:20 +0000318 oFsm.mutexFlowParams.RLock()
319 defer oFsm.mutexFlowParams.RUnlock()
mpagenko2418ab02020-11-12 12:58:06 +0000320 oFsm.clearPersistency = aClear
321}
322
mpagenko01e726e2020-10-23 09:45:29 +0000323//SetUniFlowParams verifies on existence of flow parameters to be configured,
324// optionally udates the cookie list or appends a new flow if there is space
325// if possible the FSM is trigggerd to start with the processing
mpagenko551a4d42020-12-08 18:09:20 +0000326// ignore complexity by now
327// nolint: gocyclo
328func (oFsm *UniVlanConfigFsm) SetUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +0000329 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) error {
330 loRuleParams := uniVlanRuleParams{
331 TpID: aTpID,
332 MatchVid: uint32(aMatchVlan),
333 SetVid: uint32(aSetVlan),
334 SetPcp: uint32(aSetPcp),
335 }
336 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
337 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
338 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
339
340 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
341 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
342 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
343 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
344 } else {
345 if !oFsm.acceptIncrementalEvtoOption {
346 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
347 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
348 }
349 }
350
351 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
352 // no prio/vid filtering requested
353 loRuleParams.TagsToRemove = 0 //no tag pop action
354 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
355 if loRuleParams.SetPcp == cCopyPrioFromInner {
356 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
357 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
358 // might collide with NoMatchVid/CopyPrio(/setVid) setting
359 // this was some precondition setting taken over from py adapter ..
360 loRuleParams.SetPcp = 0
361 }
362 }
363
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000364 flowEntryMatch := false
mpagenko01e726e2020-10-23 09:45:29 +0000365 flowCookieModify := false
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000366 //mutex protection is required for possible concurrent access to FSM members
367 oFsm.mutexFlowParams.Lock()
368 defer oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000369 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
370 //TODO: Verify if using e.g. hashes for the structures here for comparison may generate
371 // countable run time optimization (perhaps with including the hash in kvStore storage?)
372 if storedUniFlowParams.VlanRuleParams == loRuleParams {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000373 flowEntryMatch = true
dbainbri4d3a0dc2020-12-02 00:33:42 +0000374 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - rule already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000375 "device-id": oFsm.deviceID})
376 var cookieMatch bool
377 for _, newCookie := range aCookieSlice { // for all cookies available in the arguments
378 cookieMatch = false
379 for _, cookie := range storedUniFlowParams.CookieSlice {
380 if cookie == newCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000381 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - and cookie already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000382 "device-id": oFsm.deviceID, "cookie": cookie})
383 cookieMatch = true
384 break //found new cookie - no further search for this requested cookie
385 }
386 }
387 if !cookieMatch {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000388 logger.Debugw(ctx, "UniVlanConfigFsm flow setting -adding new cookie", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000389 "device-id": oFsm.deviceID, "cookie": newCookie})
390 //as range works with copies of the slice we have to write to the original slice!!
391 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
392 newCookie)
393 flowCookieModify = true
394 }
395 } //for all new cookies
396 break // found rule - no further rule search
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000397 }
398 }
mpagenko01e726e2020-10-23 09:45:29 +0000399 if !flowEntryMatch { //it is a new rule
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000400 if oFsm.numUniFlows < cMaxAllowedFlows {
mpagenko01e726e2020-10-23 09:45:29 +0000401 loFlowParams := uniVlanFlowParams{VlanRuleParams: loRuleParams}
402 loFlowParams.CookieSlice = make([]uint64, 0)
403 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
404 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000405 logger.Debugw(ctx, "UniVlanConfigFsm flow add", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000406 "Cookies": oFsm.uniVlanFlowParamsSlice[oFsm.numUniFlows].CookieSlice,
407 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
408 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
Girish Gowdra041dcb32020-11-16 16:54:30 -0800409 "SetPcp": loRuleParams.SetPcp, "numberofFlows": oFsm.numUniFlows + 1,
mpagenko01e726e2020-10-23 09:45:29 +0000410 "device-id": oFsm.deviceID})
411
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000412 oFsm.numUniFlows++
mpagenko01e726e2020-10-23 09:45:29 +0000413 // note: theoretical it would be possible to clear the same rule from the remove slice
414 // (for entries that have not yet been started with removal)
415 // but that is getting quite complicated - maybe a future optimization in case it should prove reasonable
416 // 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 +0000417
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000418 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
419 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
420 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
421 // calling some FSM event must be decoupled
mpagenko551a4d42020-12-08 18:09:20 +0000422 if oFsm.configuredUniFlow == 0 {
423 // this is a restart with a complete new flow, we can re-use the initial flow config control
424 // including the check, if the related techProfile is (still) available (probably also removed in between)
425 // calling some FSM event must be decoupled
426 go func(a_pBaseFsm *fsm.FSM) {
427 _ = a_pBaseFsm.Event(vlanEvRenew)
428 }(pConfigVlanStateBaseFsm)
429 } else {
430 //some further flows are to be configured
431 //tpId of the next rule to be configured
432 tpID := oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams.TpID
433 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, tpID)
434 oFsm.TpIDWaitingFor = tpID
435 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config (on setConfig)", log.Fields{
436 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "tp-id": tpID,
437 "ProfDone": loTechProfDone})
438 go func(aPBaseFsm *fsm.FSM, aTechProfDone bool) {
439 if aTechProfDone {
440 // let the vlan processing continue with next rule
441 _ = aPBaseFsm.Event(vlanEvIncrFlowConfig)
442 } else {
443 // set to waiting for Techprofile
444 _ = aPBaseFsm.Event(vlanEvWaitTPIncr)
445 }
446 }(pConfigVlanStateBaseFsm, loTechProfDone)
447 }
mpagenko01e726e2020-10-23 09:45:29 +0000448 } // if not in the appropriate state a new entry will be automatically considered later
449 // when the configDone state is reached
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000450 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000451 logger.Errorw(ctx, "UniVlanConfigFsm flow limit exceeded", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000452 "device-id": oFsm.deviceID, "flow-number": oFsm.numUniFlows})
453 return fmt.Errorf(" UniVlanConfigFsm flow limit exceeded %s", oFsm.deviceID)
454 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000455 } else {
456 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
457 if oFsm.numUniFlows == oFsm.configuredUniFlow {
458 //all requested rules really have been configured
459 // state transition notification is checked in deviceHandler
460 if oFsm.pDeviceHandler != nil {
461 //also the related TechProfile was already configured
dbainbri4d3a0dc2020-12-02 00:33:42 +0000462 logger.Debugw(ctx, "UniVlanConfigFsm rule already set - send immediate add-success event for reason update", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +0000463 "device-id": oFsm.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000464 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, oFsm.requestEvent)
mpagenkofc4f56e2020-11-04 17:17:49 +0000465 }
466 } else {
467 // avoid device reason update as the rule config connected to this flow may still be in progress
468 // and the device reason should only be updated on success of rule config
dbainbri4d3a0dc2020-12-02 00:33:42 +0000469 logger.Debugw(ctx, "UniVlanConfigFsm rule already set but configuration ongoing, suppress early add-success event for reason update",
mpagenkofc4f56e2020-11-04 17:17:49 +0000470 log.Fields{"device-id": oFsm.deviceID,
471 "NumberofRules": oFsm.numUniFlows, "Configured rules": oFsm.configuredUniFlow})
472 }
473 }
mpagenko01e726e2020-10-23 09:45:29 +0000474
475 if !flowEntryMatch || flowCookieModify { // some change was done to the flow entries
476 //permanently store flow config for reconcile case
dbainbri4d3a0dc2020-12-02 00:33:42 +0000477 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID, &oFsm.uniVlanFlowParamsSlice); err != nil {
478 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000479 return err
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000480 }
481 }
482 return nil
483}
484
mpagenko01e726e2020-10-23 09:45:29 +0000485//RemoveUniFlowParams verifies on existence of flow cookie,
486// if found removes cookie from flow cookie list and if this is empty
487// initiates removal of the flow related configuration from the ONU (via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000488func (oFsm *UniVlanConfigFsm) RemoveUniFlowParams(ctx context.Context, aCookie uint64) error {
mpagenko01e726e2020-10-23 09:45:29 +0000489 flowCookieMatch := false
490 //mutex protection is required for possible concurrent access to FSM members
491 oFsm.mutexFlowParams.Lock()
492 defer oFsm.mutexFlowParams.Unlock()
493 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
494 for i, cookie := range storedUniFlowParams.CookieSlice {
495 if cookie == aCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000496 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - cookie found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000497 "device-id": oFsm.deviceID, "cookie": cookie})
498 flowCookieMatch = true
499
500 //remove the cookie from the cookie slice and verify it is getting empty
501 if len(storedUniFlowParams.CookieSlice) == 1 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000502 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - full flow removal", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000503 "device-id": oFsm.deviceID})
504 oFsm.numUniFlows--
505
506 //create a new element for the removeVlanFlow slice
507 loRemoveParams := uniRemoveVlanFlowParams{
508 vlanRuleParams: storedUniFlowParams.VlanRuleParams,
509 cookie: storedUniFlowParams.CookieSlice[0],
510 }
511 oFsm.uniRemoveFlowsSlice = append(oFsm.uniRemoveFlowsSlice, loRemoveParams)
512
513 //and remove the actual element from the addVlanFlow slice
514 // oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = nil //automatically done by garbage collector
515 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
516 oFsm.numUniFlows = 0 //no more flows
517 oFsm.configuredUniFlow = 0 //no more flows configured
518 oFsm.uniVlanFlowParamsSlice = nil //reset the slice
mpagenko2418ab02020-11-12 12:58:06 +0000519 //at this point it is evident that no flow anymore refers to a still possibly active Techprofile
520 //request that this profile gets deleted before a new flow add is allowed
mpagenko551a4d42020-12-08 18:09:20 +0000521 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, loRemoveParams.vlanRuleParams.TpID, true)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000522 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - no more flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000523 "device-id": oFsm.deviceID})
524 } else {
525 oFsm.numUniFlows--
526 if oFsm.configuredUniFlow > 0 {
527 oFsm.configuredUniFlow--
528 //TODO!! might be needed to consider still outstanding configure requests ..
529 // so a flow at removal might still not be configured !?!
530 }
mpagenko2418ab02020-11-12 12:58:06 +0000531 usedTpID := storedUniFlowParams.VlanRuleParams.TpID
mpagenko01e726e2020-10-23 09:45:29 +0000532 //cut off the requested flow by slicing out this element
533 oFsm.uniVlanFlowParamsSlice = append(
534 oFsm.uniVlanFlowParamsSlice[:flow], oFsm.uniVlanFlowParamsSlice[flow+1:]...)
mpagenko2418ab02020-11-12 12:58:06 +0000535 //here we have to check, if there are still other flows referencing to the actual ProfileId
536 // before we can request that this profile gets deleted before a new flow add is allowed
537 tpIDInOtherFlows := false
538 for _, tpUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
539 if tpUniFlowParams.VlanRuleParams.TpID == usedTpID {
540 tpIDInOtherFlows = true
541 break // search loop can be left
542 }
543 }
544 if tpIDInOtherFlows {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000545 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is still used in other flows", log.Fields{
mpagenko2418ab02020-11-12 12:58:06 +0000546 "device-id": oFsm.deviceID, "tp-id": usedTpID})
547 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000548 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is not used anymore", log.Fields{
mpagenko2418ab02020-11-12 12:58:06 +0000549 "device-id": oFsm.deviceID, "tp-id": usedTpID})
550 //request that this profile gets deleted before a new flow add is allowed
mpagenko551a4d42020-12-08 18:09:20 +0000551 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, usedTpID, true)
mpagenko2418ab02020-11-12 12:58:06 +0000552 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000553 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow removed from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000554 "device-id": oFsm.deviceID})
555 }
556 //trigger the FSM to remove the relevant rule
557 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
558 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
559 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
560 // calling some FSM event must be decoupled
561 go func(a_pBaseFsm *fsm.FSM) {
562 _ = a_pBaseFsm.Event(vlanEvRemFlowConfig)
563 }(pConfigVlanStateBaseFsm)
564 } // if not in the appropriate state a new entry will be automatically considered later
565 // when the configDone state is reached
566 } else {
mpagenko01e726e2020-10-23 09:45:29 +0000567 //cut off the requested cookie by slicing out this element
568 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(
569 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[:i],
570 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[i+1:]...)
mpagenkofc4f56e2020-11-04 17:17:49 +0000571 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
572 // state transition notification is checked in deviceHandler
573 if oFsm.pDeviceHandler != nil {
574 //making use of the add->remove successor enum assumption/definition
dbainbri4d3a0dc2020-12-02 00:33:42 +0000575 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(uint8(oFsm.requestEvent)+1))
mpagenkofc4f56e2020-11-04 17:17:49 +0000576 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000577 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - rule persists with still valid cookies", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000578 "device-id": oFsm.deviceID, "cookies": oFsm.uniVlanFlowParamsSlice[flow].CookieSlice})
579 }
580
581 //permanently store the modified flow config for reconcile case
mpagenkofc4f56e2020-11-04 17:17:49 +0000582 if oFsm.pDeviceHandler != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000583 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID, &oFsm.uniVlanFlowParamsSlice); err != nil {
584 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +0000585 return err
586 }
mpagenko01e726e2020-10-23 09:45:29 +0000587 }
588
589 break //found the cookie - no further search for this requested cookie
590 }
591 }
592 if flowCookieMatch { //cookie already found: no need for further search in other flows
593 break
594 }
595 } //search all flows
596 if !flowCookieMatch { //some cookie remove-request for a cookie that does not exist in the FSM data
dbainbri4d3a0dc2020-12-02 00:33:42 +0000597 logger.Warnw(ctx, "UniVlanConfigFsm flow removal - remove-cookie not found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000598 "device-id": oFsm.deviceID, "remove-cookie": aCookie})
599 // but accept the request with success as no such cookie (flow) does exist
mpagenkofc4f56e2020-11-04 17:17:49 +0000600 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
601 // state transition notification is checked in deviceHandler
602 if oFsm.pDeviceHandler != nil {
603 //making use of the add->remove successor enum assumption/definition
dbainbri4d3a0dc2020-12-02 00:33:42 +0000604 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(uint8(oFsm.requestEvent)+1))
mpagenkofc4f56e2020-11-04 17:17:49 +0000605 }
mpagenko01e726e2020-10-23 09:45:29 +0000606 return nil
607 } //unknown cookie
608
609 return nil
610}
611
dbainbri4d3a0dc2020-12-02 00:33:42 +0000612func (oFsm *UniVlanConfigFsm) enterConfigStarting(ctx context.Context, e *fsm.Event) {
613 logger.Debugw(ctx, "UniVlanConfigFsm start", log.Fields{"in state": e.FSM.Current(),
mpagenko01e726e2020-10-23 09:45:29 +0000614 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000615
616 // this FSM is not intended for re-start, needs always new creation for a new run
mpagenko01e726e2020-10-23 09:45:29 +0000617 // (self-destroying - compare enterDisabled())
mpagenkodff5dda2020-08-28 11:52:01 +0000618 oFsm.omciMIdsResponseReceived = make(chan bool)
619 // start go routine for processing of LockState messages
dbainbri4d3a0dc2020-12-02 00:33:42 +0000620 go oFsm.processOmciVlanMessages(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +0000621 //let the state machine run forward from here directly
622 pConfigVlanStateAFsm := oFsm.pAdaptFsm
623 if pConfigVlanStateAFsm != nil {
624 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
mpagenko551a4d42020-12-08 18:09:20 +0000625 oFsm.mutexFlowParams.Lock()
626 tpID := oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams.TpID
627 oFsm.TpIDWaitingFor = tpID
628 oFsm.mutexFlowParams.Unlock()
629 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID))
630 //cmp also usage in EVTOCDE create in omci_cc
631 oFsm.evtocdID = macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo)
632 go func(aPAFsm *AdapterFsm, aTechProfDone bool) {
633 if aPAFsm != nil && aPAFsm.pFsm != nil {
634 if aTechProfDone {
mpagenkodff5dda2020-08-28 11:52:01 +0000635 // let the vlan processing begin
mpagenko551a4d42020-12-08 18:09:20 +0000636 _ = aPAFsm.pFsm.Event(vlanEvStartConfig)
mpagenkodff5dda2020-08-28 11:52:01 +0000637 } else {
638 // set to waiting for Techprofile
mpagenko551a4d42020-12-08 18:09:20 +0000639 _ = aPAFsm.pFsm.Event(vlanEvWaitTechProf)
mpagenkodff5dda2020-08-28 11:52:01 +0000640 }
641 }
mpagenko551a4d42020-12-08 18:09:20 +0000642 }(pConfigVlanStateAFsm, loTechProfDone)
643 } else {
644 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
645 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
646 //should never happen, else: recovery would be needed from outside the FSM
647 return
mpagenkodff5dda2020-08-28 11:52:01 +0000648 }
649}
650
dbainbri4d3a0dc2020-12-02 00:33:42 +0000651func (oFsm *UniVlanConfigFsm) enterConfigVtfd(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000652 //mutex protection is required for possible concurrent access to FSM members
653 oFsm.mutexFlowParams.Lock()
mpagenko551a4d42020-12-08 18:09:20 +0000654 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
mpagenko8b07c1b2020-11-26 10:36:31 +0000655 if len(oFsm.uniVlanFlowParamsSlice) == 0 {
656 //possibly the entry is not valid anymore based on intermediate delete requests
657 //just a basic protection ...
658 oFsm.mutexFlowParams.Unlock()
659 pConfigVlanStateAFsm := oFsm.pAdaptFsm
660 go func(a_pAFsm *AdapterFsm) {
661 _ = a_pAFsm.pFsm.Event(vlanEvReset)
662 }(pConfigVlanStateAFsm)
663 return
664 }
mpagenko01e726e2020-10-23 09:45:29 +0000665 if oFsm.uniVlanFlowParamsSlice[0].VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +0000666 // meaning transparent setup - no specific VTFD setting required
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000667 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000668 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000669 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000670 // let the FSM proceed ... (from within this state all internal pointers may be expected to be correct)
671 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
672 pConfigVlanStateAFsm := oFsm.pAdaptFsm
673 go func(a_pAFsm *AdapterFsm) {
Himani Chawla4d908332020-08-31 12:30:20 +0530674 _ = a_pAFsm.pFsm.Event(vlanEvRxConfigVtfd)
mpagenkodff5dda2020-08-28 11:52:01 +0000675 }(pConfigVlanStateAFsm)
676 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300677 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
678 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
mpagenko551a4d42020-12-08 18:09:20 +0000679 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + uint16(oFsm.uniVlanFlowParamsSlice[0].VlanRuleParams.TpID)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000680 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300681 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000682 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
683 // setVid is assumed to be masked already by the caller to 12 bit
684 oFsm.vlanFilterList[0] = uint16(oFsm.uniVlanFlowParamsSlice[0].VlanRuleParams.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000685 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000686 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000687 vtfdFilterList[0] = oFsm.vlanFilterList[0]
688 oFsm.numVlanFilterEntries = 1
mpagenkodff5dda2020-08-28 11:52:01 +0000689 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300690 EntityID: vtfdID,
mpagenkodff5dda2020-08-28 11:52:01 +0000691 Attributes: me.AttributeValueMap{
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000692 "VlanFilterList": vtfdFilterList, //omci lib wants a slice for serialization
693 "ForwardOperation": uint8(0x10), //VID investigation
694 "NumberOfEntries": oFsm.numVlanFilterEntries,
mpagenkodff5dda2020-08-28 11:52:01 +0000695 },
696 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000697 logger.Debugw(ctx, "UniVlanConfigFsm sendcreate VTFD", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000698 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000699 meInstance := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +0000700 oFsm.pAdaptFsm.commChan, meParams)
701 //accept also nil as (error) return value for writing to LastTx
702 // - this avoids misinterpretation of new received OMCI messages
703 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
704 // send shall return (dual format) error code that can be used here for immediate error treatment
705 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +0000706 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +0000707 }
708}
709
dbainbri4d3a0dc2020-12-02 00:33:42 +0000710func (oFsm *UniVlanConfigFsm) enterConfigEvtocd(ctx context.Context, e *fsm.Event) {
711 logger.Debugw(ctx, "UniVlanConfigFsm - start config EVTOCD loop", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000712 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +0000713 oFsm.requestEventOffset = 0 //0 offset for last flow-add activity
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300714 go func() {
715 tpID := oFsm.uniVlanFlowParamsSlice[0].VlanRuleParams.TpID
716 vlanID := oFsm.uniVlanFlowParamsSlice[0].VlanRuleParams.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +0000717 errEvto := oFsm.performConfigEvtocdEntries(ctx, oFsm.configuredUniFlow)
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300718 //This is correct passing scenario
719 if errEvto == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000720 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
721 logger.Infow(ctx, "Setting multicast MEs, with first flow", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300722 "techProfile": tpID, "gemPort": gemPort, "vlanID": vlanID, "configuredUniFlow": oFsm.configuredUniFlow})
723 //can Use the first elements in the slice because it's the first flow.
dbainbri4d3a0dc2020-12-02 00:33:42 +0000724 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300725 vlanID)
726 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000727 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300728 log.Fields{"device-id": oFsm.deviceID})
729 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
730 }
731 }
732 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
733 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
734 }
735 }()
mpagenkodff5dda2020-08-28 11:52:01 +0000736}
737
dbainbri4d3a0dc2020-12-02 00:33:42 +0000738func (oFsm *UniVlanConfigFsm) enterVlanConfigDone(ctx context.Context, e *fsm.Event) {
mpagenko551a4d42020-12-08 18:09:20 +0000739 oFsm.mutexFlowParams.Lock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000740 logger.Debugw(ctx, "UniVlanConfigFsm - checking on more flows", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +0000741 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
742 "overall-uni-rules": oFsm.numUniFlows, "configured-uni-rules": oFsm.configuredUniFlow})
743 pConfigVlanStateAFsm := oFsm.pAdaptFsm
744 if pConfigVlanStateAFsm == nil {
745 oFsm.mutexFlowParams.Unlock()
746 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
747 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
748 //should never happen, else: recovery would be needed from outside the FSM
749 return
750 }
751 pConfigVlanStateBaseFsm := pConfigVlanStateAFsm.pFsm
mpagenko01e726e2020-10-23 09:45:29 +0000752 if len(oFsm.uniRemoveFlowsSlice) > 0 {
mpagenko551a4d42020-12-08 18:09:20 +0000753 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000754 //some further flows are to be removed, removal always starts with the first element
755 // calling some FSM event must be decoupled
756 go func(a_pBaseFsm *fsm.FSM) {
757 _ = a_pBaseFsm.Event(vlanEvRemFlowConfig)
758 }(pConfigVlanStateBaseFsm)
759 return
760 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000761 if oFsm.numUniFlows > oFsm.configuredUniFlow {
mpagenko551a4d42020-12-08 18:09:20 +0000762 if oFsm.configuredUniFlow == 0 {
763 oFsm.mutexFlowParams.Unlock()
764 // this is a restart with a complete new flow, we can re-use the initial flow config control
765 // including the check, if the related techProfile is (still) available (probably also removed in between)
766 // calling some FSM event must be decoupled
767 go func(a_pBaseFsm *fsm.FSM) {
768 _ = a_pBaseFsm.Event(vlanEvRenew)
769 }(pConfigVlanStateBaseFsm)
770 return
771 }
772
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000773 //some further flows are to be configured
mpagenko551a4d42020-12-08 18:09:20 +0000774 //tpId of the next rule to be configured
775 tpID := oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams.TpID
776 oFsm.TpIDWaitingFor = tpID
777 oFsm.mutexFlowParams.Unlock()
778 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, tpID)
779 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config", log.Fields{
780 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "tp-id": tpID,
781 "ProfDone": loTechProfDone})
782 go func(aPBaseFsm *fsm.FSM, aTechProfDone bool) {
783 if aTechProfDone {
784 // let the vlan processing continue with next rule
785 _ = aPBaseFsm.Event(vlanEvIncrFlowConfig)
786 } else {
787 // set to waiting for Techprofile
788 _ = aPBaseFsm.Event(vlanEvWaitTPIncr)
789 }
790 }(pConfigVlanStateBaseFsm, loTechProfDone)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000791 return
792 }
mpagenko551a4d42020-12-08 18:09:20 +0000793 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000794 logger.Debugw(ctx, "UniVlanConfigFsm - VLAN config done: send dh event notification", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000795 "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000796 // it might appear that some flows are requested also after 'flowPushed' event has been generated ...
797 // state transition notification is checked in deviceHandler
mpagenko551a4d42020-12-08 18:09:20 +0000798 // note: 'flowPushed' event is only generated if all 'pending' rules are configured
mpagenkodff5dda2020-08-28 11:52:01 +0000799 if oFsm.pDeviceHandler != nil {
mpagenkofc4f56e2020-11-04 17:17:49 +0000800 //making use of the add->remove successor enum assumption/definition
dbainbri4d3a0dc2020-12-02 00:33:42 +0000801 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(uint8(oFsm.requestEvent)+oFsm.requestEventOffset))
mpagenkodff5dda2020-08-28 11:52:01 +0000802 }
803}
804
dbainbri4d3a0dc2020-12-02 00:33:42 +0000805func (oFsm *UniVlanConfigFsm) enterConfigIncrFlow(ctx context.Context, e *fsm.Event) {
806 logger.Debugw(ctx, "UniVlanConfigFsm - start config further incremental flow", log.Fields{
Girish Gowdra041dcb32020-11-16 16:54:30 -0800807 "in state": e.FSM.Current(), "recent flow-number": oFsm.configuredUniFlow,
mpagenko01e726e2020-10-23 09:45:29 +0000808 "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000809 oFsm.mutexFlowParams.Lock()
mpagenko551a4d42020-12-08 18:09:20 +0000810 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000811
mpagenko8b07c1b2020-11-26 10:36:31 +0000812 if uint8(len(oFsm.uniVlanFlowParamsSlice)) < oFsm.configuredUniFlow {
813 //possibly the entry is not valid anymore based on intermediate delete requests
814 //just a basic protection ...
815 oFsm.mutexFlowParams.Unlock()
816 pConfigVlanStateAFsm := oFsm.pAdaptFsm
817 go func(a_pAFsm *AdapterFsm) {
818 _ = a_pAFsm.pFsm.Event(vlanEvReset)
819 }(pConfigVlanStateAFsm)
820 return
821 }
mpagenko01e726e2020-10-23 09:45:29 +0000822 if oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000823 // meaning transparent setup - no specific VTFD setting required
824 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000825 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000826 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000827 } else {
828 if oFsm.numVlanFilterEntries == 0 {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300829 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
830 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
mpagenko551a4d42020-12-08 18:09:20 +0000831 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + uint16(oFsm.uniVlanFlowParamsSlice[0].VlanRuleParams.TpID)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000832 //no VTFD yet created
dbainbri4d3a0dc2020-12-02 00:33:42 +0000833 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300834 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000835 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300836 // FIXME: VOL-3673: using oFsm.uniVlanFlowParamsSlice[0] is incorrect here, as the relevant (first) VTFD may
837 // result from some incremented rule (not all rules enforce a VTFD configuration). But this is Ok for the
838 // current scenarios we support.
839 // 'SetVid' below is assumed to be masked already by the caller to 12 bit
840 oFsm.vlanFilterList[0] = uint16(oFsm.uniVlanFlowParamsSlice[0].VlanRuleParams.SetVid)
841
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000842 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000843 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000844 vtfdFilterList[0] = oFsm.vlanFilterList[0]
845 oFsm.numVlanFilterEntries = 1
846 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300847 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000848 Attributes: me.AttributeValueMap{
849 "VlanFilterList": vtfdFilterList,
850 "ForwardOperation": uint8(0x10), //VID investigation
851 "NumberOfEntries": oFsm.numVlanFilterEntries,
852 },
853 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000854 meInstance := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000855 oFsm.pAdaptFsm.commChan, meParams)
856 //accept also nil as (error) return value for writing to LastTx
857 // - this avoids misinterpretation of new received OMCI messages
858 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
859 // send shall return (dual format) error code that can be used here for immediate error treatment
860 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +0000861 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000862 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300863 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
864 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
mpagenko551a4d42020-12-08 18:09:20 +0000865 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID +
866 uint16(oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams.TpID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300867
dbainbri4d3a0dc2020-12-02 00:33:42 +0000868 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300869 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000870 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000871 // setVid is assumed to be masked already by the caller to 12 bit
872 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] =
mpagenko01e726e2020-10-23 09:45:29 +0000873 uint16(oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams.SetVid)
mpagenko01e726e2020-10-23 09:45:29 +0000874 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300875
876 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
877 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
878 // new vlan associated with a different TP.
879 vtfdFilterList[0] = uint16(oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams.SetVid)
880 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000881
882 oFsm.numVlanFilterEntries++
883 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300884 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000885 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300886 "VlanFilterList": vtfdFilterList,
887 "ForwardOperation": uint8(0x10), //VID investigation
888 "NumberOfEntries": oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000889 },
890 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000891 meInstance := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000892 oFsm.pAdaptFsm.commChan, meParams)
893 //accept also nil as (error) return value for writing to LastTx
894 // - this avoids misinterpretation of new received OMCI messages
895 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
896 // send shall return (dual format) error code that can be used here for immediate error treatment
897 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +0000898 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000899 }
900 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +0000901 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000902 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000903 logger.Errorw(ctx, "VTFD create/set failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +0000904 log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +0000905 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
906 go func(a_pBaseFsm *fsm.FSM) {
907 _ = a_pBaseFsm.Event(vlanEvReset)
908 }(pConfigVlanStateBaseFsm)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000909 return
910 }
911 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000912 oFsm.requestEventOffset = 0 //0 offset for last flow-add activity
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300913 go func() {
914 tpID := oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams.TpID
dbainbri4d3a0dc2020-12-02 00:33:42 +0000915 errEvto := oFsm.performConfigEvtocdEntries(ctx, oFsm.configuredUniFlow)
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300916 //This is correct passing scenario
917 if errEvto == nil {
918 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
dbainbri4d3a0dc2020-12-02 00:33:42 +0000919 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300920 vlanID := oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow-1].VlanRuleParams.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +0000921 logger.Infow(ctx, "Setting multicast MEs for additional flows", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300922 "techProfile": tpID, "gemPort": gemPort,
923 "vlanID": vlanID, "configuredUniFlow": oFsm.configuredUniFlow})
924 //-1 is to use the last configured flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000925 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300926 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000927 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300928 log.Fields{"device-id": oFsm.deviceID})
929 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
930 }
931 }
932 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
933 }
934 }()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000935}
936
dbainbri4d3a0dc2020-12-02 00:33:42 +0000937func (oFsm *UniVlanConfigFsm) enterRemoveFlow(ctx context.Context, e *fsm.Event) {
mpagenko551a4d42020-12-08 18:09:20 +0000938 oFsm.mutexFlowParams.RLock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000939 logger.Debugw(ctx, "UniVlanConfigFsm - start removing the top remove-flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000940 "in state": e.FSM.Current(), "with last cookie": oFsm.uniRemoveFlowsSlice[0].cookie,
941 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000942
mpagenkofc4f56e2020-11-04 17:17:49 +0000943 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
944 loAllowSpecificOmciConfig := oFsm.pDeviceHandler.ReadyForSpecificOmciConfig
mpagenko01e726e2020-10-23 09:45:29 +0000945 loVlanEntryClear := uint8(0)
946 loVlanEntryRmPos := uint8(0x80) //with indication 'invalid' in bit 7
947 //shallow copy is sufficient as no reference variables are used within struct
948 loRuleParams := oFsm.uniRemoveFlowsSlice[0].vlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +0000949 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000950 logger.Debugw(ctx, "UniVlanConfigFsm - remove-flow parameters are", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000951 "match vid": loRuleParams.MatchVid, "match Pcp": loRuleParams.MatchPcp,
952 "set vid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
953 "device-id": oFsm.deviceID})
954
955 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
956 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +0000957 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD removal required for transparent flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000958 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
959 } else {
960 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization and 're-copy'
961 if oFsm.numVlanFilterEntries == 1 {
mpagenko551a4d42020-12-08 18:09:20 +0000962 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + uint16(loRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +0000963 //only one active VLAN entry (hopefully the SetVID we want to remove - should be, but not verified ..)
964 // so we can just delete the VTFD entry
dbainbri4d3a0dc2020-12-02 00:33:42 +0000965 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD delete (no more vlan filters)",
mpagenko01e726e2020-10-23 09:45:29 +0000966 log.Fields{"current vlan list": oFsm.vlanFilterList,
967 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +0000968 loVlanEntryClear = 1 //full VlanFilter clear request
969 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
dbainbri4d3a0dc2020-12-02 00:33:42 +0000970 meInstance := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300971 oFsm.pAdaptFsm.commChan, vtfdID)
mpagenkofc4f56e2020-11-04 17:17:49 +0000972 oFsm.pLastTxMeInstance = meInstance
973 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000974 logger.Debugw(ctx, "UniVlanConfigFsm delete VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000975 "device-id": oFsm.deviceID, "device-state": deviceReasonMap[oFsm.pDeviceHandler.deviceReason]})
mpagenkofc4f56e2020-11-04 17:17:49 +0000976 }
mpagenko01e726e2020-10-23 09:45:29 +0000977 } else {
978 //many VTFD already should exists - find and remove the one concerned by the actual remove rule
979 // by updating the VTFD per set command with new valid list
dbainbri4d3a0dc2020-12-02 00:33:42 +0000980 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD removal of requested VLAN from the list on OMCI",
mpagenko01e726e2020-10-23 09:45:29 +0000981 log.Fields{"current vlan list": oFsm.vlanFilterList,
982 "set-vlan": loRuleParams.SetVid, "device-id": oFsm.deviceID})
983 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
984 if loRuleParams.SetVid == uint32(oFsm.vlanFilterList[i]) {
985 loVlanEntryRmPos = i
986 break //abort search
987 }
988 }
989 if loVlanEntryRmPos < cVtfdTableSize {
mpagenko551a4d42020-12-08 18:09:20 +0000990 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + uint16(loRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +0000991 //valid entry was found - to be eclipsed
992 loVlanEntryClear = 2 //VlanFilter remove request for a specific entry
993 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
994 if i < loVlanEntryRmPos {
995 vtfdFilterList[i] = oFsm.vlanFilterList[i] //copy original
996 } else if i < (cVtfdTableSize - 1) {
997 vtfdFilterList[i] = oFsm.vlanFilterList[i+1] //copy successor (including 0 elements)
998 } else {
999 vtfdFilterList[i] = 0 //set last byte if needed
1000 }
1001 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001002 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001003 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001004 "new vlan list": vtfdFilterList, "device-id": oFsm.deviceID})
1005
mpagenkofc4f56e2020-11-04 17:17:49 +00001006 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001007 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
dbainbri4d3a0dc2020-12-02 00:33:42 +00001008 meInstance := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001009 oFsm.pAdaptFsm.commChan, vtfdID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001010 oFsm.pLastTxMeInstance = meInstance
1011 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001012 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001013 "device-id": oFsm.deviceID, "device-state": deviceReasonMap[oFsm.pDeviceHandler.deviceReason]})
mpagenko01e726e2020-10-23 09:45:29 +00001014 }
mpagenko01e726e2020-10-23 09:45:29 +00001015 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001016 logger.Warnw(ctx, "UniVlanConfigFsm: requested VLAN for removal not found in list - ignore and continue (no VTFD set)",
mpagenko01e726e2020-10-23 09:45:29 +00001017 log.Fields{"device-id": oFsm.deviceID})
1018 }
1019 }
1020 if loVlanEntryClear > 0 {
mpagenkofc4f56e2020-11-04 17:17:49 +00001021 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
1022 //waiting on response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001023 err := oFsm.waitforOmciResponse(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001024 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001025 logger.Errorw(ctx, "VTFD delete/reset failed, aborting VlanConfig FSM!",
mpagenkofc4f56e2020-11-04 17:17:49 +00001026 log.Fields{"device-id": oFsm.deviceID})
1027 // calling some FSM event must be decoupled
1028 go func(a_pBaseFsm *fsm.FSM) {
1029 _ = a_pBaseFsm.Event(vlanEvReset)
1030 }(pConfigVlanStateBaseFsm)
1031 return
1032 }
mpagenko01e726e2020-10-23 09:45:29 +00001033 }
1034
1035 if loVlanEntryClear == 1 {
1036 oFsm.vlanFilterList[0] = 0 //first entry is the only that can contain the previous only-one element
1037 oFsm.numVlanFilterEntries = 0
1038 } else if loVlanEntryClear == 2 {
1039 // new VlanFilterList should be one entry smaller now - copy from last configured entry
1040 // this loop now includes the 0 element on previous last valid entry
1041 for i := uint8(0); i <= oFsm.numVlanFilterEntries; i++ {
1042 oFsm.vlanFilterList[i] = vtfdFilterList[i]
1043 }
1044 oFsm.numVlanFilterEntries--
1045 }
1046 }
1047 }
1048
mpagenkofc4f56e2020-11-04 17:17:49 +00001049 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001050 go oFsm.removeEvtocdEntries(ctx, loRuleParams)
mpagenkofc4f56e2020-11-04 17:17:49 +00001051 } else {
1052 // OMCI processing is not done, expectation is to have the ONU in some basic config state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001053 logger.Debugw(ctx, "UniVlanConfigFsm remove EVTOCD OMCI handling skipped based on device state", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +00001054 "device-id": oFsm.deviceID})
1055 // calling some FSM event must be decoupled
1056 go func(a_pBaseFsm *fsm.FSM) {
1057 _ = a_pBaseFsm.Event(vlanEvRemFlowDone)
1058 }(pConfigVlanStateBaseFsm)
1059 }
mpagenkodff5dda2020-08-28 11:52:01 +00001060}
1061
dbainbri4d3a0dc2020-12-02 00:33:42 +00001062func (oFsm *UniVlanConfigFsm) enterVlanCleanupDone(ctx context.Context, e *fsm.Event) {
1063 logger.Debugw(ctx, "UniVlanConfigFsm - removing the removal data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001064 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001065
mpagenko01e726e2020-10-23 09:45:29 +00001066 oFsm.mutexFlowParams.Lock()
1067 if len(oFsm.uniRemoveFlowsSlice) <= 1 {
1068 oFsm.uniRemoveFlowsSlice = nil //reset the slice
dbainbri4d3a0dc2020-12-02 00:33:42 +00001069 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - last remove-flow deleted", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001070 "device-id": oFsm.deviceID})
1071 } else {
1072 //cut off the actual flow by slicing out the first element
1073 oFsm.uniRemoveFlowsSlice = append(
1074 oFsm.uniRemoveFlowsSlice[:0],
1075 oFsm.uniRemoveFlowsSlice[1:]...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001076 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow deleted from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001077 "device-id": oFsm.deviceID})
1078 }
1079 oFsm.mutexFlowParams.Unlock()
1080
mpagenkofc4f56e2020-11-04 17:17:49 +00001081 oFsm.requestEventOffset = 1 //offset 1 for last flow-remove activity
mpagenko01e726e2020-10-23 09:45:29 +00001082 //return to the basic config verification state
mpagenkodff5dda2020-08-28 11:52:01 +00001083 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1084 if pConfigVlanStateAFsm != nil {
1085 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
1086 go func(a_pAFsm *AdapterFsm) {
1087 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001088 _ = a_pAFsm.pFsm.Event(vlanEvFlowDataRemoved)
mpagenkodff5dda2020-08-28 11:52:01 +00001089 }
1090 }(pConfigVlanStateAFsm)
1091 }
1092}
1093
dbainbri4d3a0dc2020-12-02 00:33:42 +00001094func (oFsm *UniVlanConfigFsm) enterResetting(ctx context.Context, e *fsm.Event) {
1095 logger.Debugw(ctx, "UniVlanConfigFsm resetting", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001096
1097 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1098 if pConfigVlanStateAFsm != nil {
1099 // abort running message processing
1100 fsmAbortMsg := Message{
1101 Type: TestMsg,
1102 Data: TestMessage{
1103 TestMessageVal: AbortMessageProcessing,
1104 },
1105 }
1106 pConfigVlanStateAFsm.commChan <- fsmAbortMsg
1107
1108 //try to restart the FSM to 'disabled', decouple event transfer
1109 go func(a_pAFsm *AdapterFsm) {
1110 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301111 _ = a_pAFsm.pFsm.Event(vlanEvRestart)
mpagenkodff5dda2020-08-28 11:52:01 +00001112 }
1113 }(pConfigVlanStateAFsm)
1114 }
1115}
1116
dbainbri4d3a0dc2020-12-02 00:33:42 +00001117func (oFsm *UniVlanConfigFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
1118 logger.Debugw(ctx, "UniVlanConfigFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001119 oFsm.pLastTxMeInstance = nil
mpagenkodff5dda2020-08-28 11:52:01 +00001120 if oFsm.pDeviceHandler != nil {
mpagenko2418ab02020-11-12 12:58:06 +00001121 //TODO: to clarify with improved error treatment for VlanConfigFsm (timeout,reception) errors
1122 // current code removes the complete FSM including all flow/rule configuration done so far
1123 // this might be a bit to much, it would require fully new flow config from rwCore (at least on OnuDown/up)
1124 // maybe a more sophisticated approach is possible without clearing the data
1125 if oFsm.clearPersistency {
1126 //permanently remove possibly stored persistent data
1127 if len(oFsm.uniVlanFlowParamsSlice) > 0 {
1128 var emptySlice = make([]uniVlanFlowParams, 0)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001129 _ = oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID, &emptySlice) //ignore errors
mpagenko2418ab02020-11-12 12:58:06 +00001130 }
1131 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001132 logger.Debugw(ctx, "UniVlanConfigFsm persistency data not cleared", log.Fields{"device-id": oFsm.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001133 }
1134 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001135 go oFsm.pDeviceHandler.RemoveVlanFilterFsm(ctx, oFsm.pOnuUniPort)
mpagenkodff5dda2020-08-28 11:52:01 +00001136 }
1137}
1138
dbainbri4d3a0dc2020-12-02 00:33:42 +00001139func (oFsm *UniVlanConfigFsm) processOmciVlanMessages(ctx context.Context) { //ctx context.Context?
1140 logger.Debugw(ctx, "Start UniVlanConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001141loop:
1142 for {
mpagenkodff5dda2020-08-28 11:52:01 +00001143 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00001144 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001145 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +05301146 message, ok := <-oFsm.pAdaptFsm.commChan
1147 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001148 logger.Info(ctx, "UniVlanConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301149 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
1150 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1151 break loop
1152 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001153 logger.Debugw(ctx, "UniVlanConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301154
1155 switch message.Type {
1156 case TestMsg:
1157 msg, _ := message.Data.(TestMessage)
1158 if msg.TestMessageVal == AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001159 logger.Infow(ctx, "UniVlanConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001160 break loop
1161 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001162 logger.Warnw(ctx, "UniVlanConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Himani Chawla4d908332020-08-31 12:30:20 +05301163 case OMCI:
1164 msg, _ := message.Data.(OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001165 oFsm.handleOmciVlanConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301166 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001167 logger.Warn(ctx, "UniVlanConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301168 "message.Type": message.Type})
mpagenkodff5dda2020-08-28 11:52:01 +00001169 }
1170 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001171 logger.Infow(ctx, "End UniVlanConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001172}
1173
dbainbri4d3a0dc2020-12-02 00:33:42 +00001174func (oFsm *UniVlanConfigFsm) handleOmciVlanConfigMessage(ctx context.Context, msg OmciMessage) {
1175 logger.Debugw(ctx, "Rx OMCI UniVlanConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001176 "msgType": msg.OmciMsg.MessageType})
1177
1178 switch msg.OmciMsg.MessageType {
1179 case omci.CreateResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001180 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001181 if err := oFsm.handleOmciCreateResponseMessage(ctx, msg.OmciPacket); err != nil {
1182 logger.Warnw(ctx, "CreateResponse handling aborted", log.Fields{"err": err})
mpagenkodff5dda2020-08-28 11:52:01 +00001183 return
1184 }
mpagenkodff5dda2020-08-28 11:52:01 +00001185 } //CreateResponseType
1186 case omci.SetResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001187 { //leave that here as direct code as most often used
mpagenkodff5dda2020-08-28 11:52:01 +00001188 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1189 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001190 logger.Errorw(ctx, "Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001191 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001192 return
1193 }
1194 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1195 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001196 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001197 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001198 return
1199 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001200 logger.Debugw(ctx, "UniVlanConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkodff5dda2020-08-28 11:52:01 +00001201 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001202 logger.Errorw(ctx, "UniVlanConfigFsm Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001203 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
mpagenkodff5dda2020-08-28 11:52:01 +00001204 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1205 return
1206 }
mpagenko01e726e2020-10-23 09:45:29 +00001207 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1208 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1209 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001210 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "MulticastOperationsProfile":
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001211 { // let the MultiEntity config proceed by stopping the wait function
mpagenkodff5dda2020-08-28 11:52:01 +00001212 oFsm.omciMIdsResponseReceived <- true
1213 }
1214 }
1215 }
1216 } //SetResponseType
mpagenko01e726e2020-10-23 09:45:29 +00001217 case omci.DeleteResponseType:
1218 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001219 if err := oFsm.handleOmciDeleteResponseMessage(ctx, msg.OmciPacket); err != nil {
1220 logger.Warnw(ctx, "DeleteResponse handling aborted", log.Fields{"err": err})
mpagenko01e726e2020-10-23 09:45:29 +00001221 return
1222 }
1223 } //DeleteResponseType
mpagenkodff5dda2020-08-28 11:52:01 +00001224 default:
1225 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001226 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00001227 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001228 return
1229 }
1230 }
1231}
1232
dbainbri4d3a0dc2020-12-02 00:33:42 +00001233func (oFsm *UniVlanConfigFsm) handleOmciCreateResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00001234 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeCreateResponse)
1235 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001236 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001237 log.Fields{"device-id": oFsm.deviceID})
1238 return fmt.Errorf("omci msg layer could not be detected for CreateResponse for device-id %x",
1239 oFsm.deviceID)
1240 }
1241 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
1242 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001243 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001244 log.Fields{"device-id": oFsm.deviceID})
1245 return fmt.Errorf("omci msg layer could not be assigned for CreateResponse for device-id %x",
1246 oFsm.deviceID)
1247 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001248 logger.Debugw(ctx, "UniVlanConfigFsm CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001249 if msgObj.Result != me.Success && msgObj.Result != me.InstanceExists {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001250 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"device-id": oFsm.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00001251 "Error": msgObj.Result})
1252 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1253 return fmt.Errorf("omci CreateResponse Error for device-id %x",
1254 oFsm.deviceID)
1255 }
1256 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1257 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1258 // to satisfy StaticCodeAnalysis I had to move the small processing into a separate method :-(
1259 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001260 case "VlanTaggingFilterData", "MulticastOperationsProfile",
1261 "MulticastSubscriberConfigInfo", "MacBridgePortConfigurationData",
1262 "ExtendedVlanTaggingOperationConfigurationData":
mpagenko01e726e2020-10-23 09:45:29 +00001263 {
1264 if oFsm.pAdaptFsm.pFsm.Current() == vlanStConfigVtfd {
1265 // Only if CreateResponse is received from first flow entry - let the FSM proceed ...
1266 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigVtfd)
1267 } else { // let the MultiEntity config proceed by stopping the wait function
1268 oFsm.omciMIdsResponseReceived <- true
1269 }
1270 }
1271 }
1272 }
1273 return nil
1274}
1275
dbainbri4d3a0dc2020-12-02 00:33:42 +00001276func (oFsm *UniVlanConfigFsm) handleOmciDeleteResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00001277 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeDeleteResponse)
1278 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001279 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001280 log.Fields{"device-id": oFsm.deviceID})
1281 return fmt.Errorf("omci msg layer could not be detected for DeleteResponse for device-id %x",
1282 oFsm.deviceID)
1283 }
1284 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
1285 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001286 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001287 log.Fields{"device-id": oFsm.deviceID})
1288 return fmt.Errorf("omci msg layer could not be assigned for DeleteResponse for device-id %x",
1289 oFsm.deviceID)
1290 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001291 logger.Debugw(ctx, "UniVlanConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko01e726e2020-10-23 09:45:29 +00001292 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001293 logger.Errorw(ctx, "UniVlanConfigFsm - Omci DeleteResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001294 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1295 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1296 return fmt.Errorf("omci DeleteResponse Error for device-id %x",
1297 oFsm.deviceID)
1298 }
1299 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1300 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1301 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001302 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData":
mpagenko01e726e2020-10-23 09:45:29 +00001303 { // let the MultiEntity config proceed by stopping the wait function
1304 oFsm.omciMIdsResponseReceived <- true
1305 }
1306 }
1307 }
1308 return nil
1309}
1310
dbainbri4d3a0dc2020-12-02 00:33:42 +00001311func (oFsm *UniVlanConfigFsm) performConfigEvtocdEntries(ctx context.Context, aFlowEntryNo uint8) error {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001312 if aFlowEntryNo == 0 {
1313 // EthType set only at first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00001314 // EVTOCD ME is expected to exist at this point already from MIB-Download (with AssociationType/Pointer)
1315 // we need to extend the configuration by EthType definition and, to be sure, downstream 'inverse' mode
dbainbri4d3a0dc2020-12-02 00:33:42 +00001316 logger.Debugw(ctx, "UniVlanConfigFsm Tx Create::EVTOCD", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00001317 "EntitytId": strconv.FormatInt(int64(oFsm.evtocdID), 16),
1318 "i/oEthType": strconv.FormatInt(int64(cDefaultTpid), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001319 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001320 associationType := 2 // default to uniPPTP
1321 if oFsm.pOnuUniPort.portType == uniVEIP {
1322 associationType = 10
1323 }
1324 // Create the EVTOCD ME
mpagenkodff5dda2020-08-28 11:52:01 +00001325 meParams := me.ParamData{
1326 EntityID: oFsm.evtocdID,
1327 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001328 "InputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
1329 "OutputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
1330 "DownstreamMode": uint8(cDefaultDownstreamMode),
1331 "AssociationType": uint8(associationType),
1332 "AssociatedMePointer": oFsm.pOnuUniPort.entityID,
mpagenkodff5dda2020-08-28 11:52:01 +00001333 },
1334 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001335 meInstance := oFsm.pOmciCC.sendCreateEvtocdVar(context.TODO(), ConstDefaultOmciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001336 oFsm.pAdaptFsm.commChan, meParams)
1337 //accept also nil as (error) return value for writing to LastTx
1338 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001339 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001340
1341 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001342 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001343 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001344 logger.Errorw(ctx, "Evtocd create failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001345 log.Fields{"device-id": oFsm.deviceID})
1346 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1347 return fmt.Errorf("evtocd create failed %s, error %s", oFsm.deviceID, err)
1348 }
1349
1350 // Set the EVTOCD ME default params
1351 meParams = me.ParamData{
1352 EntityID: oFsm.evtocdID,
1353 Attributes: me.AttributeValueMap{
1354 "InputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
1355 "OutputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
1356 "DownstreamMode": uint8(cDefaultDownstreamMode),
1357 },
1358 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001359 meInstance = oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001360 oFsm.pAdaptFsm.commChan, meParams)
1361 //accept also nil as (error) return value for writing to LastTx
1362 // - this avoids misinterpretation of new received OMCI messages
1363 oFsm.pLastTxMeInstance = meInstance
1364
1365 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001366 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001367 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001368 logger.Errorw(ctx, "Evtocd set TPID failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001369 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301370 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001371 return fmt.Errorf("evtocd set TPID failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00001372 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001373 } //first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00001374
mpagenko551a4d42020-12-08 18:09:20 +00001375 oFsm.mutexFlowParams.RLock()
mpagenko8b07c1b2020-11-26 10:36:31 +00001376 if uint8(len(oFsm.uniVlanFlowParamsSlice)) < aFlowEntryNo {
1377 //possibly the entry is not valid anymore based on intermediate delete requests
1378 //just a basic protection ...
mpagenko551a4d42020-12-08 18:09:20 +00001379 oFsm.mutexFlowParams.RUnlock()
mpagenko8b07c1b2020-11-26 10:36:31 +00001380 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1381 go func(a_pAFsm *AdapterFsm) {
1382 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1383 }(pConfigVlanStateAFsm)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001384 return nil
mpagenko8b07c1b2020-11-26 10:36:31 +00001385 }
1386
mpagenko01e726e2020-10-23 09:45:29 +00001387 if oFsm.uniVlanFlowParamsSlice[aFlowEntryNo].VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00001388 //transparent transmission required
mpagenko551a4d42020-12-08 18:09:20 +00001389 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001390 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged transparent rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001391 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001392 sliceEvtocdRule := make([]uint8, 16)
1393 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1394 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1395 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1396 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1397 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1398
1399 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1400 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
1401 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1402 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1403 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1404
1405 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1406 0<<cTreatTTROffset| // Do not pop any tags
1407 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1408 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1409 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1410
1411 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1412 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
1413 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1414 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
1415
1416 meParams := me.ParamData{
1417 EntityID: oFsm.evtocdID,
1418 Attributes: me.AttributeValueMap{
1419 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1420 },
1421 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001422 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001423 oFsm.pAdaptFsm.commChan, meParams)
1424 //accept also nil as (error) return value for writing to LastTx
1425 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001426 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001427
1428 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001429 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001430 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001431 logger.Errorw(ctx, "Evtocd set transparent singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001432 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301433 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001434 return fmt.Errorf("evtocd set transparent singletagged rule failed %s, error %s", oFsm.deviceID, err)
1435
mpagenkodff5dda2020-08-28 11:52:01 +00001436 }
1437 } else {
1438 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
1439 if oFsm.acceptIncrementalEvtoOption {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001440 matchPcp := oFsm.uniVlanFlowParamsSlice[aFlowEntryNo].VlanRuleParams.MatchPcp
1441 matchVid := oFsm.uniVlanFlowParamsSlice[aFlowEntryNo].VlanRuleParams.MatchVid
1442 setPcp := oFsm.uniVlanFlowParamsSlice[aFlowEntryNo].VlanRuleParams.SetPcp
1443 setVid := oFsm.uniVlanFlowParamsSlice[aFlowEntryNo].VlanRuleParams.SetVid
mpagenkodff5dda2020-08-28 11:52:01 +00001444 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001445 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged translation rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001446 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001447 sliceEvtocdRule := make([]uint8, 16)
1448 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1449 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1450 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1451 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1452 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1453
1454 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
mpagenko01e726e2020-10-23 09:45:29 +00001455 oFsm.uniVlanFlowParamsSlice[aFlowEntryNo].VlanRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
1456 oFsm.uniVlanFlowParamsSlice[aFlowEntryNo].VlanRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
mpagenkodff5dda2020-08-28 11:52:01 +00001457 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1458 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1459
1460 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
mpagenko01e726e2020-10-23 09:45:29 +00001461 oFsm.uniVlanFlowParamsSlice[aFlowEntryNo].VlanRuleParams.TagsToRemove<<cTreatTTROffset| // either 1 or 0
mpagenkodff5dda2020-08-28 11:52:01 +00001462 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1463 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1464 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1465
1466 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
mpagenko01e726e2020-10-23 09:45:29 +00001467 oFsm.uniVlanFlowParamsSlice[aFlowEntryNo].VlanRuleParams.SetPcp<<cTreatPrioOffset| // as configured in flow
1468 oFsm.uniVlanFlowParamsSlice[aFlowEntryNo].VlanRuleParams.SetVid<<cTreatVidOffset| //as configured in flow
mpagenkodff5dda2020-08-28 11:52:01 +00001469 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00001470 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001471
1472 meParams := me.ParamData{
1473 EntityID: oFsm.evtocdID,
1474 Attributes: me.AttributeValueMap{
1475 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1476 },
1477 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001478 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001479 oFsm.pAdaptFsm.commChan, meParams)
1480 //accept also nil as (error) return value for writing to LastTx
1481 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001482 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001483
1484 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001485 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001486 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001487 logger.Errorw(ctx, "Evtocd set singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001488 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301489 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001490 return fmt.Errorf("evtocd set singletagged translation rule failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00001491 }
1492 } else {
1493 //not transparent and not acceptIncrementalEvtoOption untagged/priotagged->singletagged
1494 { // just for local var's
1495 // this defines stacking scenario: untagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00001496 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD untagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001497 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001498 sliceEvtocdRule := make([]uint8, 16)
1499 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1500 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1501 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1502 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1503 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1504
1505 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1506 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
1507 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1508 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1509 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1510
1511 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1512 0<<cTreatTTROffset| // Do not pop any tags
1513 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1514 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1515 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1516
1517 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1518 0<<cTreatPrioOffset| // vlan prio set to 0
1519 // (as done in Py code, maybe better option would be setPcp here, which still could be 0?)
mpagenko01e726e2020-10-23 09:45:29 +00001520 oFsm.uniVlanFlowParamsSlice[aFlowEntryNo].VlanRuleParams.SetVid<<cTreatVidOffset| // Outer VID don't care
mpagenkodff5dda2020-08-28 11:52:01 +00001521 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
1522
mpagenko551a4d42020-12-08 18:09:20 +00001523 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001524 meParams := me.ParamData{
1525 EntityID: oFsm.evtocdID,
1526 Attributes: me.AttributeValueMap{
1527 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1528 },
1529 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001530 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001531 oFsm.pAdaptFsm.commChan, meParams)
1532 //accept also nil as (error) return value for writing to LastTx
1533 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001534 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001535
1536 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001537 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001538 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001539 logger.Errorw(ctx, "Evtocd set untagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001540 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301541 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001542 return fmt.Errorf("evtocd set untagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
1543
mpagenkodff5dda2020-08-28 11:52:01 +00001544 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001545 } // just for local var's
mpagenkodff5dda2020-08-28 11:52:01 +00001546 { // just for local var's
1547 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00001548 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD priotagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001549 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001550 sliceEvtocdRule := make([]uint8, 16)
1551 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1552 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1553 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1554 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1555 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1556
1557 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1558 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
1559 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
1560 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1561 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1562
1563 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1564 1<<cTreatTTROffset| // pop the prio-tag
1565 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1566 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1567 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1568
mpagenko551a4d42020-12-08 18:09:20 +00001569 oFsm.mutexFlowParams.RLock()
mpagenkodff5dda2020-08-28 11:52:01 +00001570 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1571 cCopyPrioFromInner<<cTreatPrioOffset| // vlan copy from PrioTag
1572 // (as done in Py code, maybe better option would be setPcp here, which still could be PrioCopy?)
mpagenko01e726e2020-10-23 09:45:29 +00001573 oFsm.uniVlanFlowParamsSlice[aFlowEntryNo].VlanRuleParams.SetVid<<cTreatVidOffset| // Outer VID as configured
mpagenkodff5dda2020-08-28 11:52:01 +00001574 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00001575 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001576
1577 meParams := me.ParamData{
1578 EntityID: oFsm.evtocdID,
1579 Attributes: me.AttributeValueMap{
1580 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1581 },
1582 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001583 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001584 oFsm.pAdaptFsm.commChan, meParams)
1585 //accept also nil as (error) return value for writing to LastTx
1586 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001587 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001588
1589 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001590 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001591 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001592 logger.Errorw(ctx, "Evtocd set priotagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001593 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301594 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001595 return fmt.Errorf("evtocd set priotagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
1596
mpagenkodff5dda2020-08-28 11:52:01 +00001597 }
1598 } //just for local var's
1599 }
1600 }
1601
mpagenkofc4f56e2020-11-04 17:17:49 +00001602 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001603 logger.Debugw(ctx, "EVTOCD set loop finished", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001604 oFsm.configuredUniFlow++ // one (more) flow configured
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001605 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00001606}
1607
dbainbri4d3a0dc2020-12-02 00:33:42 +00001608func (oFsm *UniVlanConfigFsm) removeEvtocdEntries(ctx context.Context, aRuleParams uniVlanRuleParams) {
mpagenko01e726e2020-10-23 09:45:29 +00001609 // configured Input/Output TPID is not modified again - no influence if no filter is applied
1610 if aRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
1611 //transparent transmission was set
1612 //perhaps the config is not needed for removal,
1613 // but the specific InnerTpid setting is removed in favor of the real default forwarding rule
dbainbri4d3a0dc2020-12-02 00:33:42 +00001614 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset to default single tagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001615 "device-id": oFsm.deviceID})
1616 sliceEvtocdRule := make([]uint8, 16)
1617 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1618 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1619 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1620 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1621 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1622
1623 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1624 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
1625 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1626 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1627 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1628
1629 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1630 0<<cTreatTTROffset| // Do not pop any tags
1631 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1632 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1633 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1634
1635 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1636 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
1637 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1638 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
1639
1640 meParams := me.ParamData{
1641 EntityID: oFsm.evtocdID,
1642 Attributes: me.AttributeValueMap{
1643 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1644 },
1645 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001646 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00001647 oFsm.pAdaptFsm.commChan, meParams)
1648 //accept also nil as (error) return value for writing to LastTx
1649 // - this avoids misinterpretation of new received OMCI messages
1650 oFsm.pLastTxMeInstance = meInstance
1651
1652 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001653 err := oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001654 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001655 logger.Errorw(ctx, "Evtocd reset singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001656 log.Fields{"device-id": oFsm.deviceID})
1657 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1658 return
1659 }
1660 } else {
1661 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
1662 if oFsm.acceptIncrementalEvtoOption {
1663 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001664 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear single tagged translation rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001665 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
1666 sliceEvtocdRule := make([]uint8, 16)
1667 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1668 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1669 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1670 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1671 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1672
1673 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1674 aRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
1675 aRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
1676 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1677 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1678
1679 // delete indication for the indicated Filter
1680 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
1681 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
1682
1683 meParams := me.ParamData{
1684 EntityID: oFsm.evtocdID,
1685 Attributes: me.AttributeValueMap{
1686 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1687 },
1688 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001689 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00001690 oFsm.pAdaptFsm.commChan, meParams)
1691 //accept also nil as (error) return value for writing to LastTx
1692 // - this avoids misinterpretation of new received OMCI messages
1693 oFsm.pLastTxMeInstance = meInstance
1694
1695 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001696 err := oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001697 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001698 logger.Errorw(ctx, "Evtocd clear singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001699 log.Fields{"device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
1700 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1701 return
1702 }
1703 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001704 // VOL-3685
1705 // NOTE: With ALPHA ONUs it was seen that just resetting a particular entry in the EVTOCD table
1706 // and re-configuring a new entry would not work. The old entry is removed and new entry is created
1707 // indeed, but the traffic landing upstream would carry old vlan sometimes.
1708 // This is only a WORKAROUND which basically deletes the entire EVTOCD ME and re-creates it again
1709 // later when the flow is being re-installed.
1710 // Of course this is applicable to case only where single service (or single tcont) is in use and
1711 // there is only one service vlan (oFsm.acceptIncrementalEvtoOption is false in this case).
1712 // Interstingly this problem has not been observed in multi-tcont (or multi-service) scenario (in
1713 // which case the oFsm.acceptIncrementalEvtoOption is set to true).
1714 if oFsm.configuredUniFlow == 0 && !oFsm.acceptIncrementalEvtoOption {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001715 logger.Debugw(ctx, "UniVlanConfigFsm Tx Remove::EVTOCD", log.Fields{"device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001716 // When there are no more EVTOCD vlan configurations on the ONU and acceptIncrementalEvtoOption
1717 // is not enabled, delete the EVTOCD ME.
mpagenko01e726e2020-10-23 09:45:29 +00001718 meParams := me.ParamData{
1719 EntityID: oFsm.evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00001720 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001721 meInstance := oFsm.pOmciCC.sendDeleteEvtocd(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00001722 oFsm.pAdaptFsm.commChan, meParams)
1723 //accept also nil as (error) return value for writing to LastTx
1724 // - this avoids misinterpretation of new received OMCI messages
1725 oFsm.pLastTxMeInstance = meInstance
1726
1727 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001728 err := oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001729 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001730 logger.Errorw(ctx, "Evtocd delete rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001731 log.Fields{"device-id": oFsm.deviceID})
1732 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1733 return
1734 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001735 } else {
1736 // NOTE : We should ideally never ether this section when oFsm.acceptIncrementalEvtoOption is set to false
1737 // This is true for only ATT/DT workflow
dbainbri4d3a0dc2020-12-02 00:33:42 +00001738 logger.Debugw(ctx, "UniVlanConfigFsm: Remove EVTOCD set operation",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001739 log.Fields{"configured-flow": oFsm.configuredUniFlow, "incremental-evto": oFsm.acceptIncrementalEvtoOption})
1740 //not transparent and not acceptIncrementalEvtoOption: untagged/priotagged->singletagged
1741 { // just for local var's
1742 // this defines stacking scenario: untagged->singletagged
1743 //TODO!! in theory there could be different rules running in setting different PCP/VID'S
1744 // for untagged/priotagged, last rule wins (and remains the only one), maybe that should be
1745 // checked already at flow-add (and rejected) - to be observed if such is possible in Voltha
1746 // delete now assumes there is only one such rule!
dbainbri4d3a0dc2020-12-02 00:33:42 +00001747 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset untagged rule to default", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001748 "device-id": oFsm.deviceID})
1749 sliceEvtocdRule := make([]uint8, 16)
1750 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1751 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1752 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1753 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1754 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00001755
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001756 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1757 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
1758 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1759 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1760 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00001761
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001762 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1763 0<<cTreatTTROffset| // Do not pop any tags
1764 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1765 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1766 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
mpagenko01e726e2020-10-23 09:45:29 +00001767
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001768 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1769 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
1770 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1771 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
mpagenko01e726e2020-10-23 09:45:29 +00001772
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001773 meParams := me.ParamData{
1774 EntityID: oFsm.evtocdID,
1775 Attributes: me.AttributeValueMap{
1776 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1777 },
1778 }
1779 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(context.TODO(), ConstDefaultOmciTimeout, true,
1780 oFsm.pAdaptFsm.commChan, meParams)
1781 //accept also nil as (error) return value for writing to LastTx
1782 // - this avoids misinterpretation of new received OMCI messages
1783 oFsm.pLastTxMeInstance = meInstance
1784
1785 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001786 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001787 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001788 logger.Errorw(ctx, "Evtocd reset untagged rule to default failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001789 log.Fields{"device-id": oFsm.deviceID})
1790 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1791 return
1792 }
1793 } // just for local var's
1794 { // just for local var's
1795 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00001796 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD delete priotagged rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001797 "device-id": oFsm.deviceID})
1798 sliceEvtocdRule := make([]uint8, 16)
1799 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1800 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1801 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1802 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1803 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1804
1805 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1806 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
1807 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
1808 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1809 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1810
1811 // delete indication for the indicated Filter
1812 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
1813 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
1814
1815 meParams := me.ParamData{
1816 EntityID: oFsm.evtocdID,
1817 Attributes: me.AttributeValueMap{
1818 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1819 },
1820 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001821 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001822 oFsm.pAdaptFsm.commChan, meParams)
1823 //accept also nil as (error) return value for writing to LastTx
1824 // - this avoids misinterpretation of new received OMCI messages
1825 oFsm.pLastTxMeInstance = meInstance
1826
1827 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001828 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001829 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001830 logger.Errorw(ctx, "Evtocd delete priotagged rule failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001831 log.Fields{"device-id": oFsm.deviceID})
1832 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1833 return
1834 }
mpagenko01e726e2020-10-23 09:45:29 +00001835 }
1836 } //just for local var's
1837 }
1838 }
1839
mpagenkofc4f56e2020-11-04 17:17:49 +00001840 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001841 logger.Debugw(ctx, "EVTOCD filter remove loop finished", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001842 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRemFlowDone)
1843}
1844
dbainbri4d3a0dc2020-12-02 00:33:42 +00001845func (oFsm *UniVlanConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenkodff5dda2020-08-28 11:52:01 +00001846 select {
Himani Chawla26e555c2020-08-31 12:30:20 +05301847 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenkodff5dda2020-08-28 11:52:01 +00001848 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00001849 // logger.Infow(ctx,"LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001850 case <-time.After(30 * time.Second): //AS FOR THE OTHER OMCI FSM's
dbainbri4d3a0dc2020-12-02 00:33:42 +00001851 logger.Warnw(ctx, "UniVlanConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001852 return fmt.Errorf("uniVlanConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00001853 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05301854 if success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001855 logger.Debug(ctx, "UniVlanConfigFsm multi entity response received")
mpagenkodff5dda2020-08-28 11:52:01 +00001856 return nil
1857 }
1858 // should not happen so far
dbainbri4d3a0dc2020-12-02 00:33:42 +00001859 logger.Warnw(ctx, "UniVlanConfigFsm multi entity response error", log.Fields{"for device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001860 return fmt.Errorf("uniVlanConfigFsm multi entity responseError %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00001861 }
1862}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001863
mpagenko551a4d42020-12-08 18:09:20 +00001864func (oFsm *UniVlanConfigFsm) performSettingMulticastME(ctx context.Context, tpID uint8, multicastGemPortID uint16, vlanID uint32) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001865 logger.Debugw(ctx, "Setting Multicast MEs", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001866 "multicastGemPortID": multicastGemPortID, "vlanID": vlanID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001867 errCreateMOP := oFsm.performCreatingMulticastOperationProfile(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001868 if errCreateMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001869 logger.Errorw(ctx, "MulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001870 log.Fields{"device-id": oFsm.deviceID})
1871 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1872 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMOP)
1873 }
1874
dbainbri4d3a0dc2020-12-02 00:33:42 +00001875 errSettingMOP := oFsm.performSettingMulticastOperationProfile(ctx, multicastGemPortID, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001876 if errSettingMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001877 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001878 log.Fields{"device-id": oFsm.deviceID})
1879 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1880 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errSettingMOP)
1881 }
1882
dbainbri4d3a0dc2020-12-02 00:33:42 +00001883 errCreateMSCI := oFsm.performCreatingMulticastSubscriberConfigInfo(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001884 if errCreateMSCI != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001885 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001886 log.Fields{"device-id": oFsm.deviceID})
1887 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1888 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMSCI)
1889 }
1890
1891 meParams := me.ParamData{
1892 EntityID: macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo),
1893 Attributes: me.AttributeValueMap{
1894 "BridgeIdPointer": macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo),
1895 "PortNum": 0xf0, //fixed unique ANI side indication
1896 "TpType": 6, //MCGemIWTP
1897 "TpPointer": multicastGemPortID,
1898 },
1899 }
1900 meInstance := oFsm.pOmciCC.sendCreateMBPConfigDataVar(context.TODO(), ConstDefaultOmciTimeout, true,
1901 oFsm.pAdaptFsm.commChan, meParams)
1902 //accept also nil as (error) return value for writing to LastTx
1903 // - this avoids misinterpretation of new received OMCI messages
1904 oFsm.pLastTxMeInstance = meInstance
dbainbri4d3a0dc2020-12-02 00:33:42 +00001905 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001906 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001907 logger.Errorw(ctx, "CreateMBPConfigData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001908 log.Fields{"device-id": oFsm.deviceID, "MBPConfigDataID": macBridgeServiceProfileEID})
1909 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1910 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, err)
1911 }
1912
1913 // ==> Start creating VTFD for mcast vlan
1914
1915 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1916 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
1917 mcastVtfdID := macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo)
1918
dbainbri4d3a0dc2020-12-02 00:33:42 +00001919 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD for mcast", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001920 "EntitytId": strconv.FormatInt(int64(mcastVtfdID), 16), "mcastVlanID": vlanID,
1921 "in state": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
1922 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
1923
1924 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
1925 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
1926 // new vlan associated with a different TP.
1927 vtfdFilterList[0] = uint16(vlanID)
1928
1929 meParams = me.ParamData{
1930 EntityID: mcastVtfdID,
1931 Attributes: me.AttributeValueMap{
1932 "VlanFilterList": vtfdFilterList,
1933 "ForwardOperation": uint8(0x10), //VID investigation
1934 "NumberOfEntries": oFsm.numVlanFilterEntries,
1935 },
1936 }
1937 meInstance = oFsm.pOmciCC.sendCreateVtfdVar(context.TODO(), ConstDefaultOmciTimeout, true,
1938 oFsm.pAdaptFsm.commChan, meParams)
1939 oFsm.pLastTxMeInstance = meInstance
dbainbri4d3a0dc2020-12-02 00:33:42 +00001940 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001941 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001942 logger.Errorw(ctx, "CreateMcastVlanFilterData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001943 log.Fields{"device-id": oFsm.deviceID, "mcastVtfdID": mcastVtfdID})
1944 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1945 return fmt.Errorf("createMcastVlanFilterData responseError %s, error %s", oFsm.deviceID, err)
1946 }
1947
1948 return nil
1949}
1950
dbainbri4d3a0dc2020-12-02 00:33:42 +00001951func (oFsm *UniVlanConfigFsm) performCreatingMulticastSubscriberConfigInfo(ctx context.Context) error {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001952 instID, err := oFsm.pDeviceHandler.getUniPortMEEntityID(oFsm.pOnuUniPort.portNo)
1953 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001954 logger.Errorw(ctx, "error fetching uni port me instance",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001955 log.Fields{"device-id": oFsm.deviceID, "portNo": oFsm.pOnuUniPort.portNo})
1956 return err
1957 }
1958 meParams := me.ParamData{
1959 EntityID: instID,
1960 Attributes: me.AttributeValueMap{
1961 "MeType": 0,
1962 //Direct reference to the Operation profile
1963 //TODO ANI side used on UNI side, not the clearest option.
1964 "MulticastOperationsProfilePointer": macBridgePortAniEID + uint16(oFsm.pOnuUniPort.macBpNo),
1965 },
1966 }
1967 meInstance := oFsm.pOmciCC.sendCreateMulticastSubConfigInfoVar(context.TODO(), ConstDefaultOmciTimeout, true,
1968 oFsm.pAdaptFsm.commChan, meParams)
1969 //accept also nil as (error) return value for writing to LastTx
1970 // - this avoids misinterpretation of new received OMCI messages
1971 oFsm.pLastTxMeInstance = meInstance
1972 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001973 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001974 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001975 logger.Errorw(ctx, "CreateMulticastSubConfigInfo create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001976 log.Fields{"device-id": oFsm.deviceID, "MulticastSubConfigInfo": instID})
1977 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s", oFsm.deviceID)
1978 }
1979 return nil
1980}
1981
dbainbri4d3a0dc2020-12-02 00:33:42 +00001982func (oFsm *UniVlanConfigFsm) performCreatingMulticastOperationProfile(ctx context.Context) error {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001983 instID := macBridgePortAniEID + uint16(oFsm.pOnuUniPort.macBpNo)
1984 meParams := me.ParamData{
1985 EntityID: instID,
1986 Attributes: me.AttributeValueMap{
1987 "IgmpVersion": 2,
1988 "IgmpFunction": 0,
1989 //0 means false
1990 "ImmediateLeave": 0,
1991 "Robustness": 2,
1992 "QuerierIp": 0,
1993 "QueryInterval": 125,
1994 "QuerierMaxResponseTime": 100,
1995 "LastMemberResponseTime": 10,
1996 //0 means false
1997 "UnauthorizedJoinBehaviour": 0,
1998 },
1999 }
2000 meInstance := oFsm.pOmciCC.sendCreateMulticastOperationProfileVar(context.TODO(), ConstDefaultOmciTimeout, true,
2001 oFsm.pAdaptFsm.commChan, meParams)
2002 //accept also nil as (error) return value for writing to LastTx
2003 // - this avoids misinterpretation of new received OMCI messages
2004 oFsm.pLastTxMeInstance = meInstance
2005 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002006 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002007 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002008 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002009 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
2010 return fmt.Errorf("createMulticastOperationProfile responseError %s", oFsm.deviceID)
2011 }
2012 return nil
2013}
2014
dbainbri4d3a0dc2020-12-02 00:33:42 +00002015func (oFsm *UniVlanConfigFsm) performSettingMulticastOperationProfile(ctx context.Context, multicastGemPortID uint16, vlanID uint32) error {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002016 instID := macBridgePortAniEID + uint16(oFsm.pOnuUniPort.macBpNo)
2017 //TODO check that this is correct
2018 // Table control
2019 //setCtrl = 1
2020 //rowPartId = 0
2021 //test = 0
2022 //rowKey = 0
2023 tableCtrlStr := "0100000000000000"
2024 tableCtrl := AsByteSlice(tableCtrlStr)
2025 //TODO Building it as a Table, even though the attribute is `StringAttributeType`
2026 // see line 56 of multicastoperationsprofileframe.go, it's an error in the conversion.
2027 // FIXED 30/12/2020 Fixed for now with a local copy of multicastoperationsprofileframe.go in vendor/omci-lib-go
2028 // provided by Chip, needs upstreaming and version change.
2029 dynamicAccessCL := make([]uint8, 24)
2030 copy(dynamicAccessCL, tableCtrl)
2031 //Multicast GemPortId
2032 binary.BigEndian.PutUint16(dynamicAccessCL[2:], multicastGemPortID)
2033 // python version waits for installation of flows, see line 723 onward of
2034 // brcm_openomci_onu_handler.py
2035 binary.BigEndian.PutUint16(dynamicAccessCL[4:], uint16(vlanID))
2036 //Source IP all to 0
2037 binary.BigEndian.PutUint32(dynamicAccessCL[6:], IPToInt32(net.IPv4(0, 0, 0, 0)))
2038 //TODO start and end are hardcoded, get from TP
2039 // Destination IP address start of range
2040 binary.BigEndian.PutUint32(dynamicAccessCL[10:], IPToInt32(net.IPv4(225, 0, 0, 0)))
2041 // Destination IP address end of range
2042 binary.BigEndian.PutUint32(dynamicAccessCL[14:], IPToInt32(net.IPv4(239, 255, 255, 255)))
2043 //imputed group bandwidth
2044 binary.BigEndian.PutUint16(dynamicAccessCL[18:], 0)
2045
2046 meParams := me.ParamData{
2047 EntityID: instID,
2048 Attributes: me.AttributeValueMap{
2049 "DynamicAccessControlListTable": dynamicAccessCL,
2050 },
2051 }
2052 meInstance := oFsm.pOmciCC.sendSetMulticastOperationProfileVar(context.TODO(), ConstDefaultOmciTimeout, true,
2053 oFsm.pAdaptFsm.commChan, meParams)
2054 //accept also nil as (error) return value for writing to LastTx
2055 // - this avoids misinterpretation of new received OMCI messages
2056 oFsm.pLastTxMeInstance = meInstance
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, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002061 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
2062 return fmt.Errorf("createMulticastOperationProfile responseError %s", oFsm.deviceID)
2063 }
2064 return nil
2065}