blob: 6725098eb930303ec2ca0e432c1d8263bec62432 [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 (
Holger Hildebrandt10d98192021-01-27 15:29:31 +000080 // events of config UNI port VLAN 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 (
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000100 // states of config UNI port VLAN FSM
mpagenkodff5dda2020-08-28 11:52:01 +0000101 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)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000113const cVlanFsmIdleState = vlanStConfigDone
mpagenkodff5dda2020-08-28 11:52:01 +0000114
mpagenko01e726e2020-10-23 09:45:29 +0000115type uniVlanRuleParams struct {
mpagenko551a4d42020-12-08 18:09:20 +0000116 TpID uint8 `json:"tp_id"`
mpagenko01e726e2020-10-23 09:45:29 +0000117 MatchVid uint32 `json:"match_vid"` //use uint32 types for allowing immediate bitshifting
118 MatchPcp uint32 `json:"match_pcp"`
119 TagsToRemove uint32 `json:"tags_to_remove"`
120 SetVid uint32 `json:"set_vid"`
121 SetPcp uint32 `json:"set_pcp"`
122}
123
124type uniVlanFlowParams struct {
125 CookieSlice []uint64 `json:"cookie_slice"`
126 VlanRuleParams uniVlanRuleParams `json:"vlan_rule_params"`
127}
128
129type uniRemoveVlanFlowParams struct {
130 cookie uint64 //just the last cookie valid for removal
131 vlanRuleParams uniVlanRuleParams
132}
133
mpagenkodff5dda2020-08-28 11:52:01 +0000134//UniVlanConfigFsm defines the structure for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
135type UniVlanConfigFsm struct {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530136 pDeviceHandler *deviceHandler
mpagenko01e726e2020-10-23 09:45:29 +0000137 deviceID string
Himani Chawla6d2ae152020-09-02 13:11:20 +0530138 pOmciCC *omciCC
139 pOnuUniPort *onuUniPort
140 pUniTechProf *onuUniTechProf
141 pOnuDB *onuDeviceDB
mpagenkodff5dda2020-08-28 11:52:01 +0000142 requestEvent OnuDeviceEvent
143 omciMIdsResponseReceived chan bool //seperate channel needed for checking multiInstance OMCI message responses
144 pAdaptFsm *AdapterFsm
145 acceptIncrementalEvtoOption bool
mpagenko2418ab02020-11-12 12:58:06 +0000146 clearPersistency bool
mpagenko551a4d42020-12-08 18:09:20 +0000147 mutexFlowParams sync.RWMutex
mpagenko9a304ea2020-12-16 15:54:01 +0000148 actualUniVlanConfigRule uniVlanRuleParams
mpagenko01e726e2020-10-23 09:45:29 +0000149 uniVlanFlowParamsSlice []uniVlanFlowParams
150 uniRemoveFlowsSlice []uniRemoveVlanFlowParams
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000151 numUniFlows uint8 // expected number of flows should be less than 12
152 configuredUniFlow uint8
mpagenko01e726e2020-10-23 09:45:29 +0000153 numRemoveFlows uint8
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000154 numVlanFilterEntries uint8
mpagenko01e726e2020-10-23 09:45:29 +0000155 vlanFilterList [cVtfdTableSize]uint16
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000156 evtocdID uint16
mpagenko01e726e2020-10-23 09:45:29 +0000157 pLastTxMeInstance *me.ManagedEntity
mpagenkofc4f56e2020-11-04 17:17:49 +0000158 requestEventOffset uint8
mpagenko551a4d42020-12-08 18:09:20 +0000159 TpIDWaitingFor uint8
mpagenkodff5dda2020-08-28 11:52:01 +0000160}
161
mpagenko01e726e2020-10-23 09:45:29 +0000162//NewUniVlanConfigFsm is the 'constructor' for the state machine to config the PON ANI ports
163// of ONU UNI ports via OMCI
dbainbri4d3a0dc2020-12-02 00:33:42 +0000164func NewUniVlanConfigFsm(ctx context.Context, apDeviceHandler *deviceHandler, apDevOmciCC *omciCC, apUniPort *onuUniPort,
mpagenko551a4d42020-12-08 18:09:20 +0000165 apUniTechProf *onuUniTechProf, apOnuDB *onuDeviceDB, aTechProfileID uint8,
mpagenko01e726e2020-10-23 09:45:29 +0000166 aRequestEvent OnuDeviceEvent, aName string, aCommChannel chan Message, aAcceptIncrementalEvto bool,
167 aCookieSlice []uint64, aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) *UniVlanConfigFsm {
mpagenkodff5dda2020-08-28 11:52:01 +0000168 instFsm := &UniVlanConfigFsm{
169 pDeviceHandler: apDeviceHandler,
mpagenko01e726e2020-10-23 09:45:29 +0000170 deviceID: apDeviceHandler.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +0000171 pOmciCC: apDevOmciCC,
172 pOnuUniPort: apUniPort,
173 pUniTechProf: apUniTechProf,
174 pOnuDB: apOnuDB,
mpagenkodff5dda2020-08-28 11:52:01 +0000175 requestEvent: aRequestEvent,
176 acceptIncrementalEvtoOption: aAcceptIncrementalEvto,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000177 numUniFlows: 0,
178 configuredUniFlow: 0,
mpagenko01e726e2020-10-23 09:45:29 +0000179 numRemoveFlows: 0,
mpagenko2418ab02020-11-12 12:58:06 +0000180 clearPersistency: true,
mpagenkodff5dda2020-08-28 11:52:01 +0000181 }
182
mpagenko01e726e2020-10-23 09:45:29 +0000183 instFsm.pAdaptFsm = NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
mpagenkodff5dda2020-08-28 11:52:01 +0000184 if instFsm.pAdaptFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000185 logger.Errorw(ctx, "UniVlanConfigFsm's AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000186 "device-id": instFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000187 return nil
188 }
mpagenkodff5dda2020-08-28 11:52:01 +0000189 instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
190 vlanStDisabled,
191 fsm.Events{
192 {Name: vlanEvStart, Src: []string{vlanStDisabled}, Dst: vlanStStarting},
193 {Name: vlanEvWaitTechProf, Src: []string{vlanStStarting}, Dst: vlanStWaitingTechProf},
194 {Name: vlanEvContinueConfig, Src: []string{vlanStWaitingTechProf}, Dst: vlanStConfigVtfd},
195 {Name: vlanEvStartConfig, Src: []string{vlanStStarting}, Dst: vlanStConfigVtfd},
196 {Name: vlanEvRxConfigVtfd, Src: []string{vlanStConfigVtfd}, Dst: vlanStConfigEvtocd},
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000197 {Name: vlanEvRxConfigEvtocd, Src: []string{vlanStConfigEvtocd, vlanStConfigIncrFlow},
198 Dst: vlanStConfigDone},
mpagenko551a4d42020-12-08 18:09:20 +0000199 {Name: vlanEvRenew, Src: []string{vlanStConfigDone}, Dst: vlanStStarting},
200 {Name: vlanEvWaitTPIncr, Src: []string{vlanStConfigDone}, Dst: vlanStIncrFlowWaitTP},
201 {Name: vlanEvIncrFlowConfig, Src: []string{vlanStConfigDone, vlanStIncrFlowWaitTP},
202 Dst: vlanStConfigIncrFlow},
mpagenko01e726e2020-10-23 09:45:29 +0000203 {Name: vlanEvRemFlowConfig, Src: []string{vlanStConfigDone}, Dst: vlanStRemoveFlow},
204 {Name: vlanEvRemFlowDone, Src: []string{vlanStRemoveFlow}, Dst: vlanStCleanupDone},
205 {Name: vlanEvFlowDataRemoved, Src: []string{vlanStCleanupDone}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000206 /*
207 {Name: vlanEvTimeoutSimple, Src: []string{
208 vlanStCreatingDot1PMapper, vlanStCreatingMBPCD, vlanStSettingTconts, vlanStSettingDot1PMapper}, Dst: vlanStStarting},
209 {Name: vlanEvTimeoutMids, Src: []string{
210 vlanStCreatingGemNCTPs, vlanStCreatingGemIWs, vlanStSettingPQs}, Dst: vlanStStarting},
211 */
212 // exceptional treatment for all states except vlanStResetting
213 {Name: vlanEvReset, Src: []string{vlanStStarting, vlanStWaitingTechProf,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000214 vlanStConfigVtfd, vlanStConfigEvtocd, vlanStConfigDone, vlanStConfigIncrFlow,
mpagenko01e726e2020-10-23 09:45:29 +0000215 vlanStRemoveFlow, vlanStCleanupDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000216 Dst: vlanStResetting},
217 // the only way to get to resource-cleared disabled state again is via "resseting"
218 {Name: vlanEvRestart, Src: []string{vlanStResetting}, Dst: vlanStDisabled},
219 },
mpagenkodff5dda2020-08-28 11:52:01 +0000220 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000221 "enter_state": func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(ctx, e) },
222 "enter_" + vlanStStarting: func(e *fsm.Event) { instFsm.enterConfigStarting(ctx, e) },
223 "enter_" + vlanStConfigVtfd: func(e *fsm.Event) { instFsm.enterConfigVtfd(ctx, e) },
224 "enter_" + vlanStConfigEvtocd: func(e *fsm.Event) { instFsm.enterConfigEvtocd(ctx, e) },
225 "enter_" + vlanStConfigDone: func(e *fsm.Event) { instFsm.enterVlanConfigDone(ctx, e) },
226 "enter_" + vlanStConfigIncrFlow: func(e *fsm.Event) { instFsm.enterConfigIncrFlow(ctx, e) },
227 "enter_" + vlanStRemoveFlow: func(e *fsm.Event) { instFsm.enterRemoveFlow(ctx, e) },
228 "enter_" + vlanStCleanupDone: func(e *fsm.Event) { instFsm.enterVlanCleanupDone(ctx, e) },
229 "enter_" + vlanStResetting: func(e *fsm.Event) { instFsm.enterResetting(ctx, e) },
230 "enter_" + vlanStDisabled: func(e *fsm.Event) { instFsm.enterDisabled(ctx, e) },
mpagenkodff5dda2020-08-28 11:52:01 +0000231 },
232 )
233 if instFsm.pAdaptFsm.pFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000234 logger.Errorw(ctx, "UniVlanConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000235 "device-id": instFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000236 return nil
237 }
238
dbainbri4d3a0dc2020-12-02 00:33:42 +0000239 _ = instFsm.initUniFlowParams(ctx, aTechProfileID, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000240
dbainbri4d3a0dc2020-12-02 00:33:42 +0000241 logger.Debugw(ctx, "UniVlanConfigFsm created", log.Fields{"device-id": instFsm.deviceID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000242 "accIncrEvto": instFsm.acceptIncrementalEvtoOption})
mpagenkodff5dda2020-08-28 11:52:01 +0000243 return instFsm
244}
245
mpagenko01e726e2020-10-23 09:45:29 +0000246//initUniFlowParams is a simplified form of SetUniFlowParams() used for first flow parameters configuration
mpagenko551a4d42020-12-08 18:09:20 +0000247func (oFsm *UniVlanConfigFsm) initUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +0000248 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) error {
249 loRuleParams := uniVlanRuleParams{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000250 TpID: aTpID,
251 MatchVid: uint32(aMatchVlan),
252 SetVid: uint32(aSetVlan),
253 SetPcp: uint32(aSetPcp),
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000254 }
255 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
mpagenko01e726e2020-10-23 09:45:29 +0000256 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
257 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000258
mpagenko01e726e2020-10-23 09:45:29 +0000259 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000260 //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 +0000261 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000262 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
263 } else {
264 if !oFsm.acceptIncrementalEvtoOption {
265 //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 +0000266 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000267 }
268 }
269
mpagenko01e726e2020-10-23 09:45:29 +0000270 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000271 // no prio/vid filtering requested
mpagenko01e726e2020-10-23 09:45:29 +0000272 loRuleParams.TagsToRemove = 0 //no tag pop action
273 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
274 if loRuleParams.SetPcp == cCopyPrioFromInner {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000275 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
276 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
277 // might collide with NoMatchVid/CopyPrio(/setVid) setting
278 // this was some precondition setting taken over from py adapter ..
mpagenko01e726e2020-10-23 09:45:29 +0000279 loRuleParams.SetPcp = 0
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000280 }
281 }
mpagenko01e726e2020-10-23 09:45:29 +0000282
283 loFlowParams := uniVlanFlowParams{VlanRuleParams: loRuleParams}
284 loFlowParams.CookieSlice = make([]uint64, 0)
285 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
286
287 //no mutex protection is required for initial access and adding the first flow is always possible
288 oFsm.uniVlanFlowParamsSlice = make([]uniVlanFlowParams, 0)
289 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000290 logger.Debugw(ctx, "first UniVlanConfigFsm flow added", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000291 "Cookies": oFsm.uniVlanFlowParamsSlice[0].CookieSlice,
292 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
293 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
294 "SetPcp": loRuleParams.SetPcp,
295 "device-id": oFsm.deviceID})
296 oFsm.numUniFlows = 1
297 oFsm.uniRemoveFlowsSlice = make([]uniRemoveVlanFlowParams, 0) //initially nothing to remove
298
299 //permanently store flow config for reconcile case
dbainbri4d3a0dc2020-12-02 00:33:42 +0000300 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
mpagenko01e726e2020-10-23 09:45:29 +0000301 &oFsm.uniVlanFlowParamsSlice); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000302 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000303 return err
304 }
305
306 return nil
307}
308
mpagenko551a4d42020-12-08 18:09:20 +0000309//GetWaitingTpID returns the TpId that the FSM might be waiting for continuation (0 if none)
310func (oFsm *UniVlanConfigFsm) GetWaitingTpID() uint8 {
311 //mutex protection is required for possible concurrent access to FSM members
312 oFsm.mutexFlowParams.RLock()
313 defer oFsm.mutexFlowParams.RUnlock()
314 return oFsm.TpIDWaitingFor
315}
316
mpagenko2418ab02020-11-12 12:58:06 +0000317//RequestClearPersistency sets the internal flag to not clear persistency data (false=NoClear)
318func (oFsm *UniVlanConfigFsm) RequestClearPersistency(aClear bool) {
319 //mutex protection is required for possible concurrent access to FSM members
mpagenko551a4d42020-12-08 18:09:20 +0000320 oFsm.mutexFlowParams.RLock()
321 defer oFsm.mutexFlowParams.RUnlock()
mpagenko2418ab02020-11-12 12:58:06 +0000322 oFsm.clearPersistency = aClear
323}
324
mpagenko01e726e2020-10-23 09:45:29 +0000325//SetUniFlowParams verifies on existence of flow parameters to be configured,
326// optionally udates the cookie list or appends a new flow if there is space
327// if possible the FSM is trigggerd to start with the processing
mpagenko551a4d42020-12-08 18:09:20 +0000328// ignore complexity by now
329// nolint: gocyclo
330func (oFsm *UniVlanConfigFsm) SetUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +0000331 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) error {
332 loRuleParams := uniVlanRuleParams{
333 TpID: aTpID,
334 MatchVid: uint32(aMatchVlan),
335 SetVid: uint32(aSetVlan),
336 SetPcp: uint32(aSetPcp),
337 }
338 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
339 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
340 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
341
342 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
343 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
344 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
345 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
346 } else {
347 if !oFsm.acceptIncrementalEvtoOption {
348 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
349 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
350 }
351 }
352
353 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
354 // no prio/vid filtering requested
355 loRuleParams.TagsToRemove = 0 //no tag pop action
356 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
357 if loRuleParams.SetPcp == cCopyPrioFromInner {
358 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
359 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
360 // might collide with NoMatchVid/CopyPrio(/setVid) setting
361 // this was some precondition setting taken over from py adapter ..
362 loRuleParams.SetPcp = 0
363 }
364 }
365
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000366 flowEntryMatch := false
mpagenko01e726e2020-10-23 09:45:29 +0000367 flowCookieModify := false
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000368 //mutex protection is required for possible concurrent access to FSM members
369 oFsm.mutexFlowParams.Lock()
370 defer oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000371 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
372 //TODO: Verify if using e.g. hashes for the structures here for comparison may generate
373 // countable run time optimization (perhaps with including the hash in kvStore storage?)
374 if storedUniFlowParams.VlanRuleParams == loRuleParams {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000375 flowEntryMatch = true
dbainbri4d3a0dc2020-12-02 00:33:42 +0000376 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - rule already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000377 "device-id": oFsm.deviceID})
378 var cookieMatch bool
379 for _, newCookie := range aCookieSlice { // for all cookies available in the arguments
380 cookieMatch = false
381 for _, cookie := range storedUniFlowParams.CookieSlice {
382 if cookie == newCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000383 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - and cookie already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000384 "device-id": oFsm.deviceID, "cookie": cookie})
385 cookieMatch = true
386 break //found new cookie - no further search for this requested cookie
387 }
388 }
389 if !cookieMatch {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000390 logger.Debugw(ctx, "UniVlanConfigFsm flow setting -adding new cookie", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000391 "device-id": oFsm.deviceID, "cookie": newCookie})
392 //as range works with copies of the slice we have to write to the original slice!!
393 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
394 newCookie)
395 flowCookieModify = true
396 }
397 } //for all new cookies
398 break // found rule - no further rule search
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000399 }
400 }
mpagenko01e726e2020-10-23 09:45:29 +0000401 if !flowEntryMatch { //it is a new rule
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000402 if oFsm.numUniFlows < cMaxAllowedFlows {
mpagenko01e726e2020-10-23 09:45:29 +0000403 loFlowParams := uniVlanFlowParams{VlanRuleParams: loRuleParams}
404 loFlowParams.CookieSlice = make([]uint64, 0)
405 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
406 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000407 logger.Debugw(ctx, "UniVlanConfigFsm flow add", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000408 "Cookies": oFsm.uniVlanFlowParamsSlice[oFsm.numUniFlows].CookieSlice,
409 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
410 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
Girish Gowdra041dcb32020-11-16 16:54:30 -0800411 "SetPcp": loRuleParams.SetPcp, "numberofFlows": oFsm.numUniFlows + 1,
mpagenko01e726e2020-10-23 09:45:29 +0000412 "device-id": oFsm.deviceID})
413
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000414 oFsm.numUniFlows++
mpagenko01e726e2020-10-23 09:45:29 +0000415 // note: theoretical it would be possible to clear the same rule from the remove slice
416 // (for entries that have not yet been started with removal)
417 // but that is getting quite complicated - maybe a future optimization in case it should prove reasonable
418 // 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 +0000419
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000420 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
421 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
422 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
mpagenko551a4d42020-12-08 18:09:20 +0000423 if oFsm.configuredUniFlow == 0 {
424 // this is a restart with a complete new flow, we can re-use the initial flow config control
425 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenko9a304ea2020-12-16 15:54:01 +0000426 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +0000427 go func(a_pBaseFsm *fsm.FSM) {
428 _ = a_pBaseFsm.Event(vlanEvRenew)
429 }(pConfigVlanStateBaseFsm)
430 } else {
431 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000432 //store the actual rule that shall be worked upon in the following transient states
433 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +0000434 //tpId of the next rule to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000435 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko551a4d42020-12-08 18:09:20 +0000436 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, tpID)
437 oFsm.TpIDWaitingFor = tpID
mpagenko9a304ea2020-12-16 15:54:01 +0000438 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request (on setConfig)", log.Fields{
439 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
440 "set-Vlan": oFsm.actualUniVlanConfigRule.SetVid, "tp-id": tpID, "ProfDone": loTechProfDone})
441
mpagenko551a4d42020-12-08 18:09:20 +0000442 go func(aPBaseFsm *fsm.FSM, aTechProfDone bool) {
443 if aTechProfDone {
444 // let the vlan processing continue with next rule
445 _ = aPBaseFsm.Event(vlanEvIncrFlowConfig)
446 } else {
447 // set to waiting for Techprofile
448 _ = aPBaseFsm.Event(vlanEvWaitTPIncr)
449 }
450 }(pConfigVlanStateBaseFsm, loTechProfDone)
451 }
mpagenko01e726e2020-10-23 09:45:29 +0000452 } // if not in the appropriate state a new entry will be automatically considered later
453 // when the configDone state is reached
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000454 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000455 logger.Errorw(ctx, "UniVlanConfigFsm flow limit exceeded", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000456 "device-id": oFsm.deviceID, "flow-number": oFsm.numUniFlows})
457 return fmt.Errorf(" UniVlanConfigFsm flow limit exceeded %s", oFsm.deviceID)
458 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000459 } else {
460 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
461 if oFsm.numUniFlows == oFsm.configuredUniFlow {
462 //all requested rules really have been configured
463 // state transition notification is checked in deviceHandler
464 if oFsm.pDeviceHandler != nil {
465 //also the related TechProfile was already configured
dbainbri4d3a0dc2020-12-02 00:33:42 +0000466 logger.Debugw(ctx, "UniVlanConfigFsm rule already set - send immediate add-success event for reason update", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +0000467 "device-id": oFsm.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000468 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, oFsm.requestEvent)
mpagenkofc4f56e2020-11-04 17:17:49 +0000469 }
470 } else {
471 // avoid device reason update as the rule config connected to this flow may still be in progress
472 // and the device reason should only be updated on success of rule config
dbainbri4d3a0dc2020-12-02 00:33:42 +0000473 logger.Debugw(ctx, "UniVlanConfigFsm rule already set but configuration ongoing, suppress early add-success event for reason update",
mpagenkofc4f56e2020-11-04 17:17:49 +0000474 log.Fields{"device-id": oFsm.deviceID,
475 "NumberofRules": oFsm.numUniFlows, "Configured rules": oFsm.configuredUniFlow})
476 }
477 }
mpagenko01e726e2020-10-23 09:45:29 +0000478
479 if !flowEntryMatch || flowCookieModify { // some change was done to the flow entries
480 //permanently store flow config for reconcile case
dbainbri4d3a0dc2020-12-02 00:33:42 +0000481 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID, &oFsm.uniVlanFlowParamsSlice); err != nil {
482 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000483 return err
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000484 }
485 }
486 return nil
487}
488
mpagenko01e726e2020-10-23 09:45:29 +0000489//RemoveUniFlowParams verifies on existence of flow cookie,
490// if found removes cookie from flow cookie list and if this is empty
491// initiates removal of the flow related configuration from the ONU (via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000492func (oFsm *UniVlanConfigFsm) RemoveUniFlowParams(ctx context.Context, aCookie uint64) error {
mpagenko01e726e2020-10-23 09:45:29 +0000493 flowCookieMatch := false
494 //mutex protection is required for possible concurrent access to FSM members
495 oFsm.mutexFlowParams.Lock()
496 defer oFsm.mutexFlowParams.Unlock()
497 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
498 for i, cookie := range storedUniFlowParams.CookieSlice {
499 if cookie == aCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000500 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - cookie found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000501 "device-id": oFsm.deviceID, "cookie": cookie})
502 flowCookieMatch = true
503
504 //remove the cookie from the cookie slice and verify it is getting empty
505 if len(storedUniFlowParams.CookieSlice) == 1 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000506 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - full flow removal", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000507 "device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000508
509 //create a new element for the removeVlanFlow slice
510 loRemoveParams := uniRemoveVlanFlowParams{
511 vlanRuleParams: storedUniFlowParams.VlanRuleParams,
512 cookie: storedUniFlowParams.CookieSlice[0],
513 }
514 oFsm.uniRemoveFlowsSlice = append(oFsm.uniRemoveFlowsSlice, loRemoveParams)
515
516 //and remove the actual element from the addVlanFlow slice
517 // oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = nil //automatically done by garbage collector
518 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
519 oFsm.numUniFlows = 0 //no more flows
520 oFsm.configuredUniFlow = 0 //no more flows configured
521 oFsm.uniVlanFlowParamsSlice = nil //reset the slice
mpagenko2418ab02020-11-12 12:58:06 +0000522 //at this point it is evident that no flow anymore refers to a still possibly active Techprofile
523 //request that this profile gets deleted before a new flow add is allowed
mpagenko551a4d42020-12-08 18:09:20 +0000524 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, loRemoveParams.vlanRuleParams.TpID, true)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000525 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - no more flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000526 "device-id": oFsm.deviceID})
527 } else {
528 oFsm.numUniFlows--
529 if oFsm.configuredUniFlow > 0 {
530 oFsm.configuredUniFlow--
531 //TODO!! might be needed to consider still outstanding configure requests ..
532 // so a flow at removal might still not be configured !?!
533 }
mpagenko2418ab02020-11-12 12:58:06 +0000534 usedTpID := storedUniFlowParams.VlanRuleParams.TpID
mpagenko01e726e2020-10-23 09:45:29 +0000535 //cut off the requested flow by slicing out this element
536 oFsm.uniVlanFlowParamsSlice = append(
537 oFsm.uniVlanFlowParamsSlice[:flow], oFsm.uniVlanFlowParamsSlice[flow+1:]...)
mpagenko2418ab02020-11-12 12:58:06 +0000538 //here we have to check, if there are still other flows referencing to the actual ProfileId
539 // before we can request that this profile gets deleted before a new flow add is allowed
540 tpIDInOtherFlows := false
541 for _, tpUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
542 if tpUniFlowParams.VlanRuleParams.TpID == usedTpID {
543 tpIDInOtherFlows = true
544 break // search loop can be left
545 }
546 }
547 if tpIDInOtherFlows {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000548 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is still used in other flows", log.Fields{
mpagenko2418ab02020-11-12 12:58:06 +0000549 "device-id": oFsm.deviceID, "tp-id": usedTpID})
550 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000551 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is not used anymore", log.Fields{
mpagenko2418ab02020-11-12 12:58:06 +0000552 "device-id": oFsm.deviceID, "tp-id": usedTpID})
553 //request that this profile gets deleted before a new flow add is allowed
mpagenko551a4d42020-12-08 18:09:20 +0000554 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, usedTpID, true)
mpagenko2418ab02020-11-12 12:58:06 +0000555 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000556 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow removed from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000557 "device-id": oFsm.deviceID})
558 }
559 //trigger the FSM to remove the relevant rule
560 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
561 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
mpagenko9a304ea2020-12-16 15:54:01 +0000562 logger.Debugw(ctx, "UniVlanConfigFsm rule removal request", log.Fields{
563 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
564 "tp-id": loRemoveParams.vlanRuleParams.TpID,
565 "set-Vlan": loRemoveParams.vlanRuleParams.SetVid})
mpagenko01e726e2020-10-23 09:45:29 +0000566 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
mpagenko9a304ea2020-12-16 15:54:01 +0000567 // Can't call FSM Event directly, decoupling it
mpagenko01e726e2020-10-23 09:45:29 +0000568 go func(a_pBaseFsm *fsm.FSM) {
569 _ = a_pBaseFsm.Event(vlanEvRemFlowConfig)
570 }(pConfigVlanStateBaseFsm)
571 } // if not in the appropriate state a new entry will be automatically considered later
572 // when the configDone state is reached
573 } else {
mpagenko01e726e2020-10-23 09:45:29 +0000574 //cut off the requested cookie by slicing out this element
575 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(
576 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[:i],
577 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[i+1:]...)
mpagenkofc4f56e2020-11-04 17:17:49 +0000578 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
579 // state transition notification is checked in deviceHandler
580 if oFsm.pDeviceHandler != nil {
581 //making use of the add->remove successor enum assumption/definition
dbainbri4d3a0dc2020-12-02 00:33:42 +0000582 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(uint8(oFsm.requestEvent)+1))
mpagenkofc4f56e2020-11-04 17:17:49 +0000583 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000584 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - rule persists with still valid cookies", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000585 "device-id": oFsm.deviceID, "cookies": oFsm.uniVlanFlowParamsSlice[flow].CookieSlice})
586 }
587
588 //permanently store the modified flow config for reconcile case
mpagenkofc4f56e2020-11-04 17:17:49 +0000589 if oFsm.pDeviceHandler != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000590 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID, &oFsm.uniVlanFlowParamsSlice); err != nil {
591 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +0000592 return err
593 }
mpagenko01e726e2020-10-23 09:45:29 +0000594 }
595
596 break //found the cookie - no further search for this requested cookie
597 }
598 }
599 if flowCookieMatch { //cookie already found: no need for further search in other flows
600 break
601 }
602 } //search all flows
603 if !flowCookieMatch { //some cookie remove-request for a cookie that does not exist in the FSM data
dbainbri4d3a0dc2020-12-02 00:33:42 +0000604 logger.Warnw(ctx, "UniVlanConfigFsm flow removal - remove-cookie not found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000605 "device-id": oFsm.deviceID, "remove-cookie": aCookie})
606 // but accept the request with success as no such cookie (flow) does exist
mpagenkofc4f56e2020-11-04 17:17:49 +0000607 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
608 // state transition notification is checked in deviceHandler
609 if oFsm.pDeviceHandler != nil {
610 //making use of the add->remove successor enum assumption/definition
dbainbri4d3a0dc2020-12-02 00:33:42 +0000611 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(uint8(oFsm.requestEvent)+1))
mpagenkofc4f56e2020-11-04 17:17:49 +0000612 }
mpagenko01e726e2020-10-23 09:45:29 +0000613 return nil
614 } //unknown cookie
615
616 return nil
617}
618
dbainbri4d3a0dc2020-12-02 00:33:42 +0000619func (oFsm *UniVlanConfigFsm) enterConfigStarting(ctx context.Context, e *fsm.Event) {
620 logger.Debugw(ctx, "UniVlanConfigFsm start", log.Fields{"in state": e.FSM.Current(),
mpagenko01e726e2020-10-23 09:45:29 +0000621 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000622
623 // this FSM is not intended for re-start, needs always new creation for a new run
mpagenko01e726e2020-10-23 09:45:29 +0000624 // (self-destroying - compare enterDisabled())
mpagenkodff5dda2020-08-28 11:52:01 +0000625 oFsm.omciMIdsResponseReceived = make(chan bool)
626 // start go routine for processing of LockState messages
dbainbri4d3a0dc2020-12-02 00:33:42 +0000627 go oFsm.processOmciVlanMessages(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +0000628 //let the state machine run forward from here directly
629 pConfigVlanStateAFsm := oFsm.pAdaptFsm
630 if pConfigVlanStateAFsm != nil {
mpagenko551a4d42020-12-08 18:09:20 +0000631 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +0000632
633 //possibly the entry is not valid anymore based on intermediate delete requests
634 //just a basic protection ...
635 if len(oFsm.uniVlanFlowParamsSlice) == 0 {
636 oFsm.mutexFlowParams.Unlock()
637 logger.Debugw(ctx, "UniVlanConfigFsm start: no rule entry anymore available", log.Fields{
638 "device-id": oFsm.deviceID})
639 // Can't call FSM Event directly, decoupling it
640 go func(a_pAFsm *AdapterFsm) {
641 _ = a_pAFsm.pFsm.Event(vlanEvReset)
642 }(pConfigVlanStateAFsm)
643 return
644 }
645
646 //access to uniVlanFlowParamsSlice is done on first element only here per definition
647 //store the actual rule that shall be worked upon in the following transient states
648 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[0].VlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +0000649 oFsm.mutexFlowParams.Unlock()
mpagenko9a304ea2020-12-16 15:54:01 +0000650 tpID := oFsm.actualUniVlanConfigRule.TpID
651 oFsm.TpIDWaitingFor = tpID
mpagenko551a4d42020-12-08 18:09:20 +0000652 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID))
mpagenko9a304ea2020-12-16 15:54:01 +0000653 logger.Debugw(ctx, "UniVlanConfigFsm - start with first rule", log.Fields{
654 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
655 "set-Vlan": oFsm.actualUniVlanConfigRule.SetVid, "tp-id": tpID, "ProfDone": loTechProfDone})
mpagenko551a4d42020-12-08 18:09:20 +0000656 //cmp also usage in EVTOCDE create in omci_cc
657 oFsm.evtocdID = macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo)
mpagenko9a304ea2020-12-16 15:54:01 +0000658 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +0000659 go func(aPAFsm *AdapterFsm, aTechProfDone bool) {
660 if aPAFsm != nil && aPAFsm.pFsm != nil {
661 if aTechProfDone {
mpagenkodff5dda2020-08-28 11:52:01 +0000662 // let the vlan processing begin
mpagenko551a4d42020-12-08 18:09:20 +0000663 _ = aPAFsm.pFsm.Event(vlanEvStartConfig)
mpagenkodff5dda2020-08-28 11:52:01 +0000664 } else {
665 // set to waiting for Techprofile
mpagenko551a4d42020-12-08 18:09:20 +0000666 _ = aPAFsm.pFsm.Event(vlanEvWaitTechProf)
mpagenkodff5dda2020-08-28 11:52:01 +0000667 }
668 }
mpagenko551a4d42020-12-08 18:09:20 +0000669 }(pConfigVlanStateAFsm, loTechProfDone)
670 } else {
671 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
672 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
673 //should never happen, else: recovery would be needed from outside the FSM
674 return
mpagenkodff5dda2020-08-28 11:52:01 +0000675 }
676}
677
dbainbri4d3a0dc2020-12-02 00:33:42 +0000678func (oFsm *UniVlanConfigFsm) enterConfigVtfd(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000679 //mutex protection is required for possible concurrent access to FSM members
680 oFsm.mutexFlowParams.Lock()
mpagenko551a4d42020-12-08 18:09:20 +0000681 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
mpagenko9a304ea2020-12-16 15:54:01 +0000682 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +0000683 // meaning transparent setup - no specific VTFD setting required
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000684 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000685 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000686 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000687 // let the FSM proceed ... (from within this state all internal pointers may be expected to be correct)
mpagenkodff5dda2020-08-28 11:52:01 +0000688 pConfigVlanStateAFsm := oFsm.pAdaptFsm
mpagenko9a304ea2020-12-16 15:54:01 +0000689 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +0000690 go func(a_pAFsm *AdapterFsm) {
Himani Chawla4d908332020-08-31 12:30:20 +0530691 _ = a_pAFsm.pFsm.Event(vlanEvRxConfigVtfd)
mpagenkodff5dda2020-08-28 11:52:01 +0000692 }(pConfigVlanStateAFsm)
693 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300694 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
695 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
mpagenko9a304ea2020-12-16 15:54:01 +0000696 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + uint16(oFsm.actualUniVlanConfigRule.TpID)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000697 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300698 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000699 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
700 // setVid is assumed to be masked already by the caller to 12 bit
mpagenko9a304ea2020-12-16 15:54:01 +0000701 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000702 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000703 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000704 vtfdFilterList[0] = oFsm.vlanFilterList[0]
705 oFsm.numVlanFilterEntries = 1
mpagenkodff5dda2020-08-28 11:52:01 +0000706 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300707 EntityID: vtfdID,
mpagenkodff5dda2020-08-28 11:52:01 +0000708 Attributes: me.AttributeValueMap{
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000709 "VlanFilterList": vtfdFilterList, //omci lib wants a slice for serialization
710 "ForwardOperation": uint8(0x10), //VID investigation
711 "NumberOfEntries": oFsm.numVlanFilterEntries,
mpagenkodff5dda2020-08-28 11:52:01 +0000712 },
713 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000714 logger.Debugw(ctx, "UniVlanConfigFsm sendcreate VTFD", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000715 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000716 meInstance := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +0000717 oFsm.pAdaptFsm.commChan, meParams)
718 //accept also nil as (error) return value for writing to LastTx
719 // - this avoids misinterpretation of new received OMCI messages
720 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
721 // send shall return (dual format) error code that can be used here for immediate error treatment
722 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +0000723 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +0000724 }
725}
726
dbainbri4d3a0dc2020-12-02 00:33:42 +0000727func (oFsm *UniVlanConfigFsm) enterConfigEvtocd(ctx context.Context, e *fsm.Event) {
728 logger.Debugw(ctx, "UniVlanConfigFsm - start config EVTOCD loop", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000729 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +0000730 oFsm.requestEventOffset = 0 //0 offset for last flow-add activity
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300731 go func() {
mpagenko9a304ea2020-12-16 15:54:01 +0000732 //using the first element in the slice because it's the first flow per definition here
733 errEvto := oFsm.performConfigEvtocdEntries(ctx, 0)
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300734 //This is correct passing scenario
735 if errEvto == nil {
mpagenko9a304ea2020-12-16 15:54:01 +0000736 tpID := oFsm.actualUniVlanConfigRule.TpID
737 vlanID := oFsm.actualUniVlanConfigRule.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +0000738 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
739 logger.Infow(ctx, "Setting multicast MEs, with first flow", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300740 "techProfile": tpID, "gemPort": gemPort, "vlanID": vlanID, "configuredUniFlow": oFsm.configuredUniFlow})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000741 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300742 vlanID)
743 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000744 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300745 log.Fields{"device-id": oFsm.deviceID})
746 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
747 }
748 }
749 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
750 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
751 }
752 }()
mpagenkodff5dda2020-08-28 11:52:01 +0000753}
754
dbainbri4d3a0dc2020-12-02 00:33:42 +0000755func (oFsm *UniVlanConfigFsm) enterVlanConfigDone(ctx context.Context, e *fsm.Event) {
mpagenko9a304ea2020-12-16 15:54:01 +0000756 oFsm.mutexFlowParams.RLock()
757 defer oFsm.mutexFlowParams.RUnlock()
758
dbainbri4d3a0dc2020-12-02 00:33:42 +0000759 logger.Debugw(ctx, "UniVlanConfigFsm - checking on more flows", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +0000760 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
761 "overall-uni-rules": oFsm.numUniFlows, "configured-uni-rules": oFsm.configuredUniFlow})
762 pConfigVlanStateAFsm := oFsm.pAdaptFsm
763 if pConfigVlanStateAFsm == nil {
mpagenko551a4d42020-12-08 18:09:20 +0000764 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
765 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
766 //should never happen, else: recovery would be needed from outside the FSM
767 return
768 }
769 pConfigVlanStateBaseFsm := pConfigVlanStateAFsm.pFsm
mpagenko01e726e2020-10-23 09:45:29 +0000770 if len(oFsm.uniRemoveFlowsSlice) > 0 {
771 //some further flows are to be removed, removal always starts with the first element
mpagenko9a304ea2020-12-16 15:54:01 +0000772 logger.Debugw(ctx, "UniVlanConfigFsm rule removal from ConfigDone", log.Fields{
773 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
774 "tp-id": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.TpID,
775 "set-Vlan": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.SetVid})
776 // Can't call FSM Event directly, decoupling it
mpagenko01e726e2020-10-23 09:45:29 +0000777 go func(a_pBaseFsm *fsm.FSM) {
778 _ = a_pBaseFsm.Event(vlanEvRemFlowConfig)
779 }(pConfigVlanStateBaseFsm)
780 return
781 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000782 if oFsm.numUniFlows > oFsm.configuredUniFlow {
mpagenko551a4d42020-12-08 18:09:20 +0000783 if oFsm.configuredUniFlow == 0 {
mpagenko551a4d42020-12-08 18:09:20 +0000784 // this is a restart with a complete new flow, we can re-use the initial flow config control
785 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenko9a304ea2020-12-16 15:54:01 +0000786 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +0000787 go func(a_pBaseFsm *fsm.FSM) {
788 _ = a_pBaseFsm.Event(vlanEvRenew)
789 }(pConfigVlanStateBaseFsm)
790 return
791 }
792
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000793 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000794 //store the actual rule that shall be worked upon in the following transient states
795 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +0000796 //tpId of the next rule to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000797 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko551a4d42020-12-08 18:09:20 +0000798 oFsm.TpIDWaitingFor = tpID
mpagenko551a4d42020-12-08 18:09:20 +0000799 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, tpID)
mpagenko9a304ea2020-12-16 15:54:01 +0000800 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request", log.Fields{
801 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
802 "set-Vlan": oFsm.actualUniVlanConfigRule.SetVid, "tp-id": tpID, "ProfDone": loTechProfDone})
803 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +0000804 go func(aPBaseFsm *fsm.FSM, aTechProfDone bool) {
805 if aTechProfDone {
806 // let the vlan processing continue with next rule
807 _ = aPBaseFsm.Event(vlanEvIncrFlowConfig)
808 } else {
809 // set to waiting for Techprofile
810 _ = aPBaseFsm.Event(vlanEvWaitTPIncr)
811 }
812 }(pConfigVlanStateBaseFsm, loTechProfDone)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000813 return
814 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000815 logger.Debugw(ctx, "UniVlanConfigFsm - VLAN config done: send dh event notification", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000816 "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000817 // it might appear that some flows are requested also after 'flowPushed' event has been generated ...
818 // state transition notification is checked in deviceHandler
mpagenko551a4d42020-12-08 18:09:20 +0000819 // note: 'flowPushed' event is only generated if all 'pending' rules are configured
mpagenkodff5dda2020-08-28 11:52:01 +0000820 if oFsm.pDeviceHandler != nil {
mpagenkofc4f56e2020-11-04 17:17:49 +0000821 //making use of the add->remove successor enum assumption/definition
dbainbri4d3a0dc2020-12-02 00:33:42 +0000822 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(uint8(oFsm.requestEvent)+oFsm.requestEventOffset))
mpagenkodff5dda2020-08-28 11:52:01 +0000823 }
824}
825
dbainbri4d3a0dc2020-12-02 00:33:42 +0000826func (oFsm *UniVlanConfigFsm) enterConfigIncrFlow(ctx context.Context, e *fsm.Event) {
827 logger.Debugw(ctx, "UniVlanConfigFsm - start config further incremental flow", log.Fields{
Girish Gowdra041dcb32020-11-16 16:54:30 -0800828 "in state": e.FSM.Current(), "recent flow-number": oFsm.configuredUniFlow,
mpagenko01e726e2020-10-23 09:45:29 +0000829 "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000830 oFsm.mutexFlowParams.Lock()
mpagenko551a4d42020-12-08 18:09:20 +0000831 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000832
mpagenko9a304ea2020-12-16 15:54:01 +0000833 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000834 // meaning transparent setup - no specific VTFD setting required
835 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000836 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000837 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000838 } else {
839 if oFsm.numVlanFilterEntries == 0 {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300840 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
841 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
mpagenko9a304ea2020-12-16 15:54:01 +0000842 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + uint16(oFsm.actualUniVlanConfigRule.TpID)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000843 //no VTFD yet created
dbainbri4d3a0dc2020-12-02 00:33:42 +0000844 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300845 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000846 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300847 // 'SetVid' below is assumed to be masked already by the caller to 12 bit
mpagenko9a304ea2020-12-16 15:54:01 +0000848 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300849
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000850 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000851 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000852 vtfdFilterList[0] = oFsm.vlanFilterList[0]
853 oFsm.numVlanFilterEntries = 1
854 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300855 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000856 Attributes: me.AttributeValueMap{
857 "VlanFilterList": vtfdFilterList,
858 "ForwardOperation": uint8(0x10), //VID investigation
859 "NumberOfEntries": oFsm.numVlanFilterEntries,
860 },
861 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000862 meInstance := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000863 oFsm.pAdaptFsm.commChan, meParams)
864 //accept also nil as (error) return value for writing to LastTx
865 // - this avoids misinterpretation of new received OMCI messages
866 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
867 // send shall return (dual format) error code that can be used here for immediate error treatment
868 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +0000869 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000870 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300871 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
872 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
mpagenko551a4d42020-12-08 18:09:20 +0000873 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID +
mpagenko9a304ea2020-12-16 15:54:01 +0000874 uint16(oFsm.actualUniVlanConfigRule.TpID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300875
dbainbri4d3a0dc2020-12-02 00:33:42 +0000876 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300877 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000878 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000879 // setVid is assumed to be masked already by the caller to 12 bit
880 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] =
mpagenko9a304ea2020-12-16 15:54:01 +0000881 uint16(oFsm.actualUniVlanConfigRule.SetVid)
mpagenko01e726e2020-10-23 09:45:29 +0000882 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300883
884 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
885 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
886 // new vlan associated with a different TP.
mpagenko9a304ea2020-12-16 15:54:01 +0000887 vtfdFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300888 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000889
890 oFsm.numVlanFilterEntries++
891 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300892 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000893 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300894 "VlanFilterList": vtfdFilterList,
895 "ForwardOperation": uint8(0x10), //VID investigation
896 "NumberOfEntries": oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000897 },
898 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000899 meInstance := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000900 oFsm.pAdaptFsm.commChan, meParams)
901 //accept also nil as (error) return value for writing to LastTx
902 // - this avoids misinterpretation of new received OMCI messages
903 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
904 // send shall return (dual format) error code that can be used here for immediate error treatment
905 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +0000906 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000907 }
908 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +0000909 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000910 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000911 logger.Errorw(ctx, "VTFD create/set failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +0000912 log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +0000913 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
mpagenko9a304ea2020-12-16 15:54:01 +0000914 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +0000915 go func(a_pBaseFsm *fsm.FSM) {
916 _ = a_pBaseFsm.Event(vlanEvReset)
917 }(pConfigVlanStateBaseFsm)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000918 return
919 }
920 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000921 oFsm.requestEventOffset = 0 //0 offset for last flow-add activity
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300922 go func() {
mpagenko9a304ea2020-12-16 15:54:01 +0000923 tpID := oFsm.actualUniVlanConfigRule.TpID
dbainbri4d3a0dc2020-12-02 00:33:42 +0000924 errEvto := oFsm.performConfigEvtocdEntries(ctx, oFsm.configuredUniFlow)
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300925 //This is correct passing scenario
926 if errEvto == nil {
927 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
dbainbri4d3a0dc2020-12-02 00:33:42 +0000928 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
mpagenko9a304ea2020-12-16 15:54:01 +0000929 vlanID := oFsm.actualUniVlanConfigRule.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +0000930 logger.Infow(ctx, "Setting multicast MEs for additional flows", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300931 "techProfile": tpID, "gemPort": gemPort,
932 "vlanID": vlanID, "configuredUniFlow": oFsm.configuredUniFlow})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000933 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300934 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000935 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300936 log.Fields{"device-id": oFsm.deviceID})
937 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
938 }
939 }
940 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
941 }
942 }()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000943}
944
dbainbri4d3a0dc2020-12-02 00:33:42 +0000945func (oFsm *UniVlanConfigFsm) enterRemoveFlow(ctx context.Context, e *fsm.Event) {
mpagenko551a4d42020-12-08 18:09:20 +0000946 oFsm.mutexFlowParams.RLock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000947 logger.Debugw(ctx, "UniVlanConfigFsm - start removing the top remove-flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000948 "in state": e.FSM.Current(), "with last cookie": oFsm.uniRemoveFlowsSlice[0].cookie,
949 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000950
mpagenkofc4f56e2020-11-04 17:17:49 +0000951 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
952 loAllowSpecificOmciConfig := oFsm.pDeviceHandler.ReadyForSpecificOmciConfig
mpagenko01e726e2020-10-23 09:45:29 +0000953 loVlanEntryClear := uint8(0)
954 loVlanEntryRmPos := uint8(0x80) //with indication 'invalid' in bit 7
955 //shallow copy is sufficient as no reference variables are used within struct
956 loRuleParams := oFsm.uniRemoveFlowsSlice[0].vlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +0000957 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000958 logger.Debugw(ctx, "UniVlanConfigFsm - remove-flow parameters are", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000959 "match vid": loRuleParams.MatchVid, "match Pcp": loRuleParams.MatchPcp,
960 "set vid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
961 "device-id": oFsm.deviceID})
962
963 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
964 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +0000965 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD removal required for transparent flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000966 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
967 } else {
968 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization and 're-copy'
969 if oFsm.numVlanFilterEntries == 1 {
mpagenko551a4d42020-12-08 18:09:20 +0000970 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + uint16(loRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +0000971 //only one active VLAN entry (hopefully the SetVID we want to remove - should be, but not verified ..)
972 // so we can just delete the VTFD entry
dbainbri4d3a0dc2020-12-02 00:33:42 +0000973 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD delete (no more vlan filters)",
mpagenko01e726e2020-10-23 09:45:29 +0000974 log.Fields{"current vlan list": oFsm.vlanFilterList,
975 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +0000976 loVlanEntryClear = 1 //full VlanFilter clear request
977 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
dbainbri4d3a0dc2020-12-02 00:33:42 +0000978 meInstance := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300979 oFsm.pAdaptFsm.commChan, vtfdID)
mpagenkofc4f56e2020-11-04 17:17:49 +0000980 oFsm.pLastTxMeInstance = meInstance
981 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000982 logger.Debugw(ctx, "UniVlanConfigFsm delete VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000983 "device-id": oFsm.deviceID, "device-state": deviceReasonMap[oFsm.pDeviceHandler.deviceReason]})
mpagenkofc4f56e2020-11-04 17:17:49 +0000984 }
mpagenko01e726e2020-10-23 09:45:29 +0000985 } else {
986 //many VTFD already should exists - find and remove the one concerned by the actual remove rule
987 // by updating the VTFD per set command with new valid list
dbainbri4d3a0dc2020-12-02 00:33:42 +0000988 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD removal of requested VLAN from the list on OMCI",
mpagenko01e726e2020-10-23 09:45:29 +0000989 log.Fields{"current vlan list": oFsm.vlanFilterList,
990 "set-vlan": loRuleParams.SetVid, "device-id": oFsm.deviceID})
991 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
992 if loRuleParams.SetVid == uint32(oFsm.vlanFilterList[i]) {
993 loVlanEntryRmPos = i
994 break //abort search
995 }
996 }
997 if loVlanEntryRmPos < cVtfdTableSize {
mpagenko551a4d42020-12-08 18:09:20 +0000998 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + uint16(loRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +0000999 //valid entry was found - to be eclipsed
1000 loVlanEntryClear = 2 //VlanFilter remove request for a specific entry
1001 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1002 if i < loVlanEntryRmPos {
1003 vtfdFilterList[i] = oFsm.vlanFilterList[i] //copy original
1004 } else if i < (cVtfdTableSize - 1) {
1005 vtfdFilterList[i] = oFsm.vlanFilterList[i+1] //copy successor (including 0 elements)
1006 } else {
1007 vtfdFilterList[i] = 0 //set last byte if needed
1008 }
1009 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001010 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001011 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001012 "new vlan list": vtfdFilterList, "device-id": oFsm.deviceID})
1013
mpagenkofc4f56e2020-11-04 17:17:49 +00001014 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001015 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
dbainbri4d3a0dc2020-12-02 00:33:42 +00001016 meInstance := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001017 oFsm.pAdaptFsm.commChan, vtfdID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001018 oFsm.pLastTxMeInstance = meInstance
1019 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001020 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001021 "device-id": oFsm.deviceID, "device-state": deviceReasonMap[oFsm.pDeviceHandler.deviceReason]})
mpagenko01e726e2020-10-23 09:45:29 +00001022 }
mpagenko01e726e2020-10-23 09:45:29 +00001023 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001024 logger.Warnw(ctx, "UniVlanConfigFsm: requested VLAN for removal not found in list - ignore and continue (no VTFD set)",
mpagenko01e726e2020-10-23 09:45:29 +00001025 log.Fields{"device-id": oFsm.deviceID})
1026 }
1027 }
1028 if loVlanEntryClear > 0 {
mpagenkofc4f56e2020-11-04 17:17:49 +00001029 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
1030 //waiting on response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001031 err := oFsm.waitforOmciResponse(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001032 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001033 logger.Errorw(ctx, "VTFD delete/reset failed, aborting VlanConfig FSM!",
mpagenkofc4f56e2020-11-04 17:17:49 +00001034 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001035 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001036 go func(a_pBaseFsm *fsm.FSM) {
1037 _ = a_pBaseFsm.Event(vlanEvReset)
1038 }(pConfigVlanStateBaseFsm)
1039 return
1040 }
mpagenko01e726e2020-10-23 09:45:29 +00001041 }
1042
1043 if loVlanEntryClear == 1 {
1044 oFsm.vlanFilterList[0] = 0 //first entry is the only that can contain the previous only-one element
1045 oFsm.numVlanFilterEntries = 0
1046 } else if loVlanEntryClear == 2 {
1047 // new VlanFilterList should be one entry smaller now - copy from last configured entry
1048 // this loop now includes the 0 element on previous last valid entry
1049 for i := uint8(0); i <= oFsm.numVlanFilterEntries; i++ {
1050 oFsm.vlanFilterList[i] = vtfdFilterList[i]
1051 }
1052 oFsm.numVlanFilterEntries--
1053 }
1054 }
1055 }
1056
mpagenkofc4f56e2020-11-04 17:17:49 +00001057 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001058 go oFsm.removeEvtocdEntries(ctx, loRuleParams)
mpagenkofc4f56e2020-11-04 17:17:49 +00001059 } else {
1060 // OMCI processing is not done, expectation is to have the ONU in some basic config state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001061 logger.Debugw(ctx, "UniVlanConfigFsm remove EVTOCD OMCI handling skipped based on device state", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +00001062 "device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001063 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001064 go func(a_pBaseFsm *fsm.FSM) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001065 _ = a_pBaseFsm.Event(vlanEvRemFlowDone, loRuleParams.TpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001066 }(pConfigVlanStateBaseFsm)
1067 }
mpagenkodff5dda2020-08-28 11:52:01 +00001068}
1069
dbainbri4d3a0dc2020-12-02 00:33:42 +00001070func (oFsm *UniVlanConfigFsm) enterVlanCleanupDone(ctx context.Context, e *fsm.Event) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001071 var tpID uint8
1072 // Extract the tpID
1073 if len(e.Args) > 0 {
1074 tpID = e.Args[0].(uint8)
1075 logger.Debugw(ctx, "UniVlanConfigFsm - flow removed for tp id", log.Fields{"device-id": oFsm.deviceID, "tpID": e.Args[0].(uint8)})
1076 } else {
1077 logger.Warnw(ctx, "UniVlanConfigFsm - tp id not available", log.Fields{"device-id": oFsm.deviceID})
1078 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001079 logger.Debugw(ctx, "UniVlanConfigFsm - removing the removal data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001080 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001081
mpagenko01e726e2020-10-23 09:45:29 +00001082 oFsm.mutexFlowParams.Lock()
1083 if len(oFsm.uniRemoveFlowsSlice) <= 1 {
1084 oFsm.uniRemoveFlowsSlice = nil //reset the slice
dbainbri4d3a0dc2020-12-02 00:33:42 +00001085 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - last remove-flow deleted", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001086 "device-id": oFsm.deviceID})
1087 } else {
1088 //cut off the actual flow by slicing out the first element
1089 oFsm.uniRemoveFlowsSlice = append(
1090 oFsm.uniRemoveFlowsSlice[:0],
1091 oFsm.uniRemoveFlowsSlice[1:]...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001092 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow deleted from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001093 "device-id": oFsm.deviceID})
1094 }
1095 oFsm.mutexFlowParams.Unlock()
1096
mpagenkofc4f56e2020-11-04 17:17:49 +00001097 oFsm.requestEventOffset = 1 //offset 1 for last flow-remove activity
mpagenko01e726e2020-10-23 09:45:29 +00001098 //return to the basic config verification state
mpagenkodff5dda2020-08-28 11:52:01 +00001099 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1100 if pConfigVlanStateAFsm != nil {
mpagenko9a304ea2020-12-16 15:54:01 +00001101 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +00001102 go func(a_pAFsm *AdapterFsm) {
1103 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001104 _ = a_pAFsm.pFsm.Event(vlanEvFlowDataRemoved)
mpagenkodff5dda2020-08-28 11:52:01 +00001105 }
1106 }(pConfigVlanStateAFsm)
1107 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001108
1109 oFsm.mutexFlowParams.RLock()
1110 noOfFlowRem := len(oFsm.uniRemoveFlowsSlice)
1111 oFsm.mutexFlowParams.RUnlock()
1112 // If all pending flow removes are completed and TP ID is valid, processing any pending TP delete
1113 if noOfFlowRem == 0 && tpID > 0 {
1114 logger.Debugw(ctx, "processing pending tp delete", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID})
1115 // If we are here then all flows are removed.
1116 oFsm.pDeviceHandler.ProcessPendingTpDelete(ctx, oFsm.pOnuUniPort, tpID)
1117 }
mpagenkodff5dda2020-08-28 11:52:01 +00001118}
1119
dbainbri4d3a0dc2020-12-02 00:33:42 +00001120func (oFsm *UniVlanConfigFsm) enterResetting(ctx context.Context, e *fsm.Event) {
1121 logger.Debugw(ctx, "UniVlanConfigFsm resetting", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001122
1123 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1124 if pConfigVlanStateAFsm != nil {
1125 // abort running message processing
1126 fsmAbortMsg := Message{
1127 Type: TestMsg,
1128 Data: TestMessage{
1129 TestMessageVal: AbortMessageProcessing,
1130 },
1131 }
1132 pConfigVlanStateAFsm.commChan <- fsmAbortMsg
1133
mpagenko9a304ea2020-12-16 15:54:01 +00001134 //try to restart the FSM to 'disabled'
1135 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +00001136 go func(a_pAFsm *AdapterFsm) {
1137 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301138 _ = a_pAFsm.pFsm.Event(vlanEvRestart)
mpagenkodff5dda2020-08-28 11:52:01 +00001139 }
1140 }(pConfigVlanStateAFsm)
1141 }
1142}
1143
dbainbri4d3a0dc2020-12-02 00:33:42 +00001144func (oFsm *UniVlanConfigFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
1145 logger.Debugw(ctx, "UniVlanConfigFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001146 oFsm.pLastTxMeInstance = nil
mpagenkodff5dda2020-08-28 11:52:01 +00001147 if oFsm.pDeviceHandler != nil {
mpagenko2418ab02020-11-12 12:58:06 +00001148 //TODO: to clarify with improved error treatment for VlanConfigFsm (timeout,reception) errors
1149 // current code removes the complete FSM including all flow/rule configuration done so far
1150 // this might be a bit to much, it would require fully new flow config from rwCore (at least on OnuDown/up)
1151 // maybe a more sophisticated approach is possible without clearing the data
mpagenko9a304ea2020-12-16 15:54:01 +00001152 oFsm.mutexFlowParams.RLock()
mpagenko2418ab02020-11-12 12:58:06 +00001153 if oFsm.clearPersistency {
1154 //permanently remove possibly stored persistent data
1155 if len(oFsm.uniVlanFlowParamsSlice) > 0 {
1156 var emptySlice = make([]uniVlanFlowParams, 0)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001157 _ = oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID, &emptySlice) //ignore errors
mpagenko2418ab02020-11-12 12:58:06 +00001158 }
1159 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001160 logger.Debugw(ctx, "UniVlanConfigFsm persistency data not cleared", log.Fields{"device-id": oFsm.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001161 }
mpagenko9a304ea2020-12-16 15:54:01 +00001162 oFsm.mutexFlowParams.RUnlock()
mpagenko2418ab02020-11-12 12:58:06 +00001163 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001164 go oFsm.pDeviceHandler.RemoveVlanFilterFsm(ctx, oFsm.pOnuUniPort)
mpagenkodff5dda2020-08-28 11:52:01 +00001165 }
1166}
1167
dbainbri4d3a0dc2020-12-02 00:33:42 +00001168func (oFsm *UniVlanConfigFsm) processOmciVlanMessages(ctx context.Context) { //ctx context.Context?
1169 logger.Debugw(ctx, "Start UniVlanConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001170loop:
1171 for {
mpagenkodff5dda2020-08-28 11:52:01 +00001172 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00001173 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001174 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +05301175 message, ok := <-oFsm.pAdaptFsm.commChan
1176 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001177 logger.Info(ctx, "UniVlanConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301178 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
1179 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1180 break loop
1181 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001182 logger.Debugw(ctx, "UniVlanConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301183
1184 switch message.Type {
1185 case TestMsg:
1186 msg, _ := message.Data.(TestMessage)
1187 if msg.TestMessageVal == AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001188 logger.Infow(ctx, "UniVlanConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001189 break loop
1190 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001191 logger.Warnw(ctx, "UniVlanConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Himani Chawla4d908332020-08-31 12:30:20 +05301192 case OMCI:
1193 msg, _ := message.Data.(OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001194 oFsm.handleOmciVlanConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301195 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001196 logger.Warn(ctx, "UniVlanConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301197 "message.Type": message.Type})
mpagenkodff5dda2020-08-28 11:52:01 +00001198 }
1199 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001200 logger.Infow(ctx, "End UniVlanConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001201}
1202
dbainbri4d3a0dc2020-12-02 00:33:42 +00001203func (oFsm *UniVlanConfigFsm) handleOmciVlanConfigMessage(ctx context.Context, msg OmciMessage) {
1204 logger.Debugw(ctx, "Rx OMCI UniVlanConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001205 "msgType": msg.OmciMsg.MessageType})
1206
1207 switch msg.OmciMsg.MessageType {
1208 case omci.CreateResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001209 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001210 if err := oFsm.handleOmciCreateResponseMessage(ctx, msg.OmciPacket); err != nil {
1211 logger.Warnw(ctx, "CreateResponse handling aborted", log.Fields{"err": err})
mpagenkodff5dda2020-08-28 11:52:01 +00001212 return
1213 }
mpagenkodff5dda2020-08-28 11:52:01 +00001214 } //CreateResponseType
1215 case omci.SetResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001216 { //leave that here as direct code as most often used
mpagenkodff5dda2020-08-28 11:52:01 +00001217 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1218 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001219 logger.Errorw(ctx, "Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001220 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001221 return
1222 }
1223 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1224 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001225 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001226 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001227 return
1228 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001229 logger.Debugw(ctx, "UniVlanConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkodff5dda2020-08-28 11:52:01 +00001230 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001231 logger.Errorw(ctx, "UniVlanConfigFsm Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001232 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
mpagenkodff5dda2020-08-28 11:52:01 +00001233 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1234 return
1235 }
mpagenko01e726e2020-10-23 09:45:29 +00001236 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1237 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1238 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001239 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "MulticastOperationsProfile":
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001240 { // let the MultiEntity config proceed by stopping the wait function
mpagenkodff5dda2020-08-28 11:52:01 +00001241 oFsm.omciMIdsResponseReceived <- true
1242 }
1243 }
1244 }
1245 } //SetResponseType
mpagenko01e726e2020-10-23 09:45:29 +00001246 case omci.DeleteResponseType:
1247 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001248 if err := oFsm.handleOmciDeleteResponseMessage(ctx, msg.OmciPacket); err != nil {
1249 logger.Warnw(ctx, "DeleteResponse handling aborted", log.Fields{"err": err})
mpagenko01e726e2020-10-23 09:45:29 +00001250 return
1251 }
1252 } //DeleteResponseType
mpagenkodff5dda2020-08-28 11:52:01 +00001253 default:
1254 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001255 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00001256 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001257 return
1258 }
1259 }
1260}
1261
dbainbri4d3a0dc2020-12-02 00:33:42 +00001262func (oFsm *UniVlanConfigFsm) handleOmciCreateResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00001263 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeCreateResponse)
1264 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001265 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001266 log.Fields{"device-id": oFsm.deviceID})
1267 return fmt.Errorf("omci msg layer could not be detected for CreateResponse for device-id %x",
1268 oFsm.deviceID)
1269 }
1270 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
1271 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001272 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001273 log.Fields{"device-id": oFsm.deviceID})
1274 return fmt.Errorf("omci msg layer could not be assigned for CreateResponse for device-id %x",
1275 oFsm.deviceID)
1276 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001277 logger.Debugw(ctx, "UniVlanConfigFsm CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001278 if msgObj.Result != me.Success && msgObj.Result != me.InstanceExists {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001279 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"device-id": oFsm.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00001280 "Error": msgObj.Result})
1281 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1282 return fmt.Errorf("omci CreateResponse Error for device-id %x",
1283 oFsm.deviceID)
1284 }
1285 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1286 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1287 // to satisfy StaticCodeAnalysis I had to move the small processing into a separate method :-(
1288 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001289 case "VlanTaggingFilterData", "MulticastOperationsProfile",
1290 "MulticastSubscriberConfigInfo", "MacBridgePortConfigurationData",
1291 "ExtendedVlanTaggingOperationConfigurationData":
mpagenko01e726e2020-10-23 09:45:29 +00001292 {
1293 if oFsm.pAdaptFsm.pFsm.Current() == vlanStConfigVtfd {
1294 // Only if CreateResponse is received from first flow entry - let the FSM proceed ...
1295 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigVtfd)
1296 } else { // let the MultiEntity config proceed by stopping the wait function
1297 oFsm.omciMIdsResponseReceived <- true
1298 }
1299 }
1300 }
1301 }
1302 return nil
1303}
1304
dbainbri4d3a0dc2020-12-02 00:33:42 +00001305func (oFsm *UniVlanConfigFsm) handleOmciDeleteResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00001306 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeDeleteResponse)
1307 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001308 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001309 log.Fields{"device-id": oFsm.deviceID})
1310 return fmt.Errorf("omci msg layer could not be detected for DeleteResponse for device-id %x",
1311 oFsm.deviceID)
1312 }
1313 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
1314 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001315 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001316 log.Fields{"device-id": oFsm.deviceID})
1317 return fmt.Errorf("omci msg layer could not be assigned for DeleteResponse for device-id %x",
1318 oFsm.deviceID)
1319 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001320 logger.Debugw(ctx, "UniVlanConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko01e726e2020-10-23 09:45:29 +00001321 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001322 logger.Errorw(ctx, "UniVlanConfigFsm - Omci DeleteResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001323 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1324 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1325 return fmt.Errorf("omci DeleteResponse Error for device-id %x",
1326 oFsm.deviceID)
1327 }
1328 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1329 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1330 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001331 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData":
mpagenko01e726e2020-10-23 09:45:29 +00001332 { // let the MultiEntity config proceed by stopping the wait function
1333 oFsm.omciMIdsResponseReceived <- true
1334 }
1335 }
1336 }
1337 return nil
1338}
1339
dbainbri4d3a0dc2020-12-02 00:33:42 +00001340func (oFsm *UniVlanConfigFsm) performConfigEvtocdEntries(ctx context.Context, aFlowEntryNo uint8) error {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001341 if aFlowEntryNo == 0 {
1342 // EthType set only at first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00001343 // EVTOCD ME is expected to exist at this point already from MIB-Download (with AssociationType/Pointer)
1344 // we need to extend the configuration by EthType definition and, to be sure, downstream 'inverse' mode
dbainbri4d3a0dc2020-12-02 00:33:42 +00001345 logger.Debugw(ctx, "UniVlanConfigFsm Tx Create::EVTOCD", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00001346 "EntitytId": strconv.FormatInt(int64(oFsm.evtocdID), 16),
1347 "i/oEthType": strconv.FormatInt(int64(cDefaultTpid), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001348 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001349 associationType := 2 // default to uniPPTP
1350 if oFsm.pOnuUniPort.portType == uniVEIP {
1351 associationType = 10
1352 }
1353 // Create the EVTOCD ME
mpagenkodff5dda2020-08-28 11:52:01 +00001354 meParams := me.ParamData{
1355 EntityID: oFsm.evtocdID,
1356 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001357 "AssociationType": uint8(associationType),
1358 "AssociatedMePointer": oFsm.pOnuUniPort.entityID,
mpagenkodff5dda2020-08-28 11:52:01 +00001359 },
1360 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001361 meInstance := oFsm.pOmciCC.sendCreateEvtocdVar(context.TODO(), ConstDefaultOmciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001362 oFsm.pAdaptFsm.commChan, meParams)
1363 //accept also nil as (error) return value for writing to LastTx
1364 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001365 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001366
1367 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001368 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001369 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001370 logger.Errorw(ctx, "Evtocd create failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001371 log.Fields{"device-id": oFsm.deviceID})
1372 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1373 return fmt.Errorf("evtocd create failed %s, error %s", oFsm.deviceID, err)
1374 }
1375
1376 // Set the EVTOCD ME default params
1377 meParams = me.ParamData{
1378 EntityID: oFsm.evtocdID,
1379 Attributes: me.AttributeValueMap{
1380 "InputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
1381 "OutputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
1382 "DownstreamMode": uint8(cDefaultDownstreamMode),
1383 },
1384 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001385 meInstance = oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001386 oFsm.pAdaptFsm.commChan, meParams)
1387 //accept also nil as (error) return value for writing to LastTx
1388 // - this avoids misinterpretation of new received OMCI messages
1389 oFsm.pLastTxMeInstance = meInstance
1390
1391 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001392 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001393 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001394 logger.Errorw(ctx, "Evtocd set TPID failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001395 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301396 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001397 return fmt.Errorf("evtocd set TPID failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00001398 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001399 } //first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00001400
mpagenko551a4d42020-12-08 18:09:20 +00001401 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001402 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00001403 //transparent transmission required
mpagenko551a4d42020-12-08 18:09:20 +00001404 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001405 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged transparent rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001406 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001407 sliceEvtocdRule := make([]uint8, 16)
1408 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1409 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1410 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1411 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1412 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1413
1414 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1415 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
1416 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1417 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1418 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1419
1420 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1421 0<<cTreatTTROffset| // Do not pop any tags
1422 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1423 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1424 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1425
1426 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1427 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
1428 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1429 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
1430
1431 meParams := me.ParamData{
1432 EntityID: oFsm.evtocdID,
1433 Attributes: me.AttributeValueMap{
1434 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1435 },
1436 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001437 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001438 oFsm.pAdaptFsm.commChan, meParams)
1439 //accept also nil as (error) return value for writing to LastTx
1440 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001441 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001442
1443 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001444 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001445 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001446 logger.Errorw(ctx, "Evtocd set transparent singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001447 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301448 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001449 return fmt.Errorf("evtocd set transparent singletagged rule failed %s, error %s", oFsm.deviceID, err)
1450
mpagenkodff5dda2020-08-28 11:52:01 +00001451 }
1452 } else {
1453 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
1454 if oFsm.acceptIncrementalEvtoOption {
mpagenko9a304ea2020-12-16 15:54:01 +00001455 matchPcp := oFsm.actualUniVlanConfigRule.MatchPcp
1456 matchVid := oFsm.actualUniVlanConfigRule.MatchVid
1457 setPcp := oFsm.actualUniVlanConfigRule.SetPcp
1458 setVid := oFsm.actualUniVlanConfigRule.SetVid
mpagenkodff5dda2020-08-28 11:52:01 +00001459 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001460 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged translation rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001461 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001462 sliceEvtocdRule := make([]uint8, 16)
1463 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1464 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1465 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1466 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1467 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1468
1469 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00001470 oFsm.actualUniVlanConfigRule.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
1471 oFsm.actualUniVlanConfigRule.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
mpagenkodff5dda2020-08-28 11:52:01 +00001472 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1473 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1474
1475 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00001476 oFsm.actualUniVlanConfigRule.TagsToRemove<<cTreatTTROffset| // either 1 or 0
mpagenkodff5dda2020-08-28 11:52:01 +00001477 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1478 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1479 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1480
1481 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00001482 oFsm.actualUniVlanConfigRule.SetPcp<<cTreatPrioOffset| // as configured in flow
1483 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| //as configured in flow
mpagenkodff5dda2020-08-28 11:52:01 +00001484 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00001485 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001486
1487 meParams := me.ParamData{
1488 EntityID: oFsm.evtocdID,
1489 Attributes: me.AttributeValueMap{
1490 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1491 },
1492 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001493 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001494 oFsm.pAdaptFsm.commChan, meParams)
1495 //accept also nil as (error) return value for writing to LastTx
1496 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001497 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001498
1499 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001500 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001501 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001502 logger.Errorw(ctx, "Evtocd set singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001503 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301504 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001505 return fmt.Errorf("evtocd set singletagged translation rule failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00001506 }
1507 } else {
1508 //not transparent and not acceptIncrementalEvtoOption untagged/priotagged->singletagged
1509 { // just for local var's
1510 // this defines stacking scenario: untagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00001511 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD untagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001512 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001513 sliceEvtocdRule := make([]uint8, 16)
1514 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1515 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1516 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1517 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1518 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1519
1520 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1521 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
1522 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1523 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1524 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1525
1526 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1527 0<<cTreatTTROffset| // Do not pop any tags
1528 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1529 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1530 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1531
1532 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1533 0<<cTreatPrioOffset| // vlan prio set to 0
1534 // (as done in Py code, maybe better option would be setPcp here, which still could be 0?)
mpagenko9a304ea2020-12-16 15:54:01 +00001535 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| // Outer VID don't care
mpagenkodff5dda2020-08-28 11:52:01 +00001536 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
1537
mpagenko551a4d42020-12-08 18:09:20 +00001538 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001539 meParams := me.ParamData{
1540 EntityID: oFsm.evtocdID,
1541 Attributes: me.AttributeValueMap{
1542 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1543 },
1544 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001545 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001546 oFsm.pAdaptFsm.commChan, meParams)
1547 //accept also nil as (error) return value for writing to LastTx
1548 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001549 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001550
1551 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001552 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001553 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001554 logger.Errorw(ctx, "Evtocd set untagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001555 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301556 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001557 return fmt.Errorf("evtocd set untagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
1558
mpagenkodff5dda2020-08-28 11:52:01 +00001559 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001560 } // just for local var's
mpagenkodff5dda2020-08-28 11:52:01 +00001561 { // just for local var's
1562 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00001563 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD priotagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001564 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001565 sliceEvtocdRule := make([]uint8, 16)
1566 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1567 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1568 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1569 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1570 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1571
1572 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1573 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
1574 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
1575 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1576 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1577
1578 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1579 1<<cTreatTTROffset| // pop the prio-tag
1580 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1581 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1582 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1583
mpagenko551a4d42020-12-08 18:09:20 +00001584 oFsm.mutexFlowParams.RLock()
mpagenkodff5dda2020-08-28 11:52:01 +00001585 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1586 cCopyPrioFromInner<<cTreatPrioOffset| // vlan copy from PrioTag
1587 // (as done in Py code, maybe better option would be setPcp here, which still could be PrioCopy?)
mpagenko9a304ea2020-12-16 15:54:01 +00001588 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| // Outer VID as configured
mpagenkodff5dda2020-08-28 11:52:01 +00001589 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00001590 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001591
1592 meParams := me.ParamData{
1593 EntityID: oFsm.evtocdID,
1594 Attributes: me.AttributeValueMap{
1595 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1596 },
1597 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001598 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001599 oFsm.pAdaptFsm.commChan, meParams)
1600 //accept also nil as (error) return value for writing to LastTx
1601 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001602 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001603
1604 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001605 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001606 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001607 logger.Errorw(ctx, "Evtocd set priotagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001608 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301609 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001610 return fmt.Errorf("evtocd set priotagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
1611
mpagenkodff5dda2020-08-28 11:52:01 +00001612 }
1613 } //just for local var's
1614 }
1615 }
1616
mpagenkofc4f56e2020-11-04 17:17:49 +00001617 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001618 logger.Debugw(ctx, "EVTOCD set loop finished", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001619 oFsm.configuredUniFlow++ // one (more) flow configured
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001620 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00001621}
1622
dbainbri4d3a0dc2020-12-02 00:33:42 +00001623func (oFsm *UniVlanConfigFsm) removeEvtocdEntries(ctx context.Context, aRuleParams uniVlanRuleParams) {
mpagenko01e726e2020-10-23 09:45:29 +00001624 // configured Input/Output TPID is not modified again - no influence if no filter is applied
1625 if aRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
1626 //transparent transmission was set
1627 //perhaps the config is not needed for removal,
1628 // but the specific InnerTpid setting is removed in favor of the real default forwarding rule
dbainbri4d3a0dc2020-12-02 00:33:42 +00001629 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset to default single tagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001630 "device-id": oFsm.deviceID})
1631 sliceEvtocdRule := make([]uint8, 16)
1632 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1633 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1634 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1635 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1636 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1637
1638 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1639 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
1640 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1641 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1642 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1643
1644 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1645 0<<cTreatTTROffset| // Do not pop any tags
1646 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1647 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1648 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1649
1650 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1651 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
1652 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1653 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
1654
1655 meParams := me.ParamData{
1656 EntityID: oFsm.evtocdID,
1657 Attributes: me.AttributeValueMap{
1658 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1659 },
1660 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001661 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00001662 oFsm.pAdaptFsm.commChan, meParams)
1663 //accept also nil as (error) return value for writing to LastTx
1664 // - this avoids misinterpretation of new received OMCI messages
1665 oFsm.pLastTxMeInstance = meInstance
1666
1667 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001668 err := oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001669 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001670 logger.Errorw(ctx, "Evtocd reset singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001671 log.Fields{"device-id": oFsm.deviceID})
1672 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1673 return
1674 }
1675 } else {
1676 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
1677 if oFsm.acceptIncrementalEvtoOption {
1678 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001679 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear single tagged translation rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001680 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
1681 sliceEvtocdRule := make([]uint8, 16)
1682 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1683 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1684 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1685 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1686 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1687
1688 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1689 aRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
1690 aRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
1691 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1692 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1693
1694 // delete indication for the indicated Filter
1695 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
1696 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
1697
1698 meParams := me.ParamData{
1699 EntityID: oFsm.evtocdID,
1700 Attributes: me.AttributeValueMap{
1701 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1702 },
1703 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001704 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00001705 oFsm.pAdaptFsm.commChan, meParams)
1706 //accept also nil as (error) return value for writing to LastTx
1707 // - this avoids misinterpretation of new received OMCI messages
1708 oFsm.pLastTxMeInstance = meInstance
1709
1710 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001711 err := oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001712 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001713 logger.Errorw(ctx, "Evtocd clear singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001714 log.Fields{"device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
1715 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1716 return
1717 }
1718 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001719 // VOL-3685
1720 // NOTE: With ALPHA ONUs it was seen that just resetting a particular entry in the EVTOCD table
1721 // and re-configuring a new entry would not work. The old entry is removed and new entry is created
1722 // indeed, but the traffic landing upstream would carry old vlan sometimes.
1723 // This is only a WORKAROUND which basically deletes the entire EVTOCD ME and re-creates it again
1724 // later when the flow is being re-installed.
1725 // Of course this is applicable to case only where single service (or single tcont) is in use and
1726 // there is only one service vlan (oFsm.acceptIncrementalEvtoOption is false in this case).
1727 // Interstingly this problem has not been observed in multi-tcont (or multi-service) scenario (in
1728 // which case the oFsm.acceptIncrementalEvtoOption is set to true).
1729 if oFsm.configuredUniFlow == 0 && !oFsm.acceptIncrementalEvtoOption {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001730 logger.Debugw(ctx, "UniVlanConfigFsm Tx Remove::EVTOCD", log.Fields{"device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001731 // When there are no more EVTOCD vlan configurations on the ONU and acceptIncrementalEvtoOption
1732 // is not enabled, delete the EVTOCD ME.
mpagenko01e726e2020-10-23 09:45:29 +00001733 meParams := me.ParamData{
1734 EntityID: oFsm.evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00001735 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001736 meInstance := oFsm.pOmciCC.sendDeleteEvtocd(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00001737 oFsm.pAdaptFsm.commChan, meParams)
1738 //accept also nil as (error) return value for writing to LastTx
1739 // - this avoids misinterpretation of new received OMCI messages
1740 oFsm.pLastTxMeInstance = meInstance
1741
1742 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001743 err := oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001744 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001745 logger.Errorw(ctx, "Evtocd delete rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001746 log.Fields{"device-id": oFsm.deviceID})
1747 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1748 return
1749 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001750 } else {
1751 // NOTE : We should ideally never ether this section when oFsm.acceptIncrementalEvtoOption is set to false
1752 // This is true for only ATT/DT workflow
dbainbri4d3a0dc2020-12-02 00:33:42 +00001753 logger.Debugw(ctx, "UniVlanConfigFsm: Remove EVTOCD set operation",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001754 log.Fields{"configured-flow": oFsm.configuredUniFlow, "incremental-evto": oFsm.acceptIncrementalEvtoOption})
1755 //not transparent and not acceptIncrementalEvtoOption: untagged/priotagged->singletagged
1756 { // just for local var's
1757 // this defines stacking scenario: untagged->singletagged
1758 //TODO!! in theory there could be different rules running in setting different PCP/VID'S
1759 // for untagged/priotagged, last rule wins (and remains the only one), maybe that should be
1760 // checked already at flow-add (and rejected) - to be observed if such is possible in Voltha
1761 // delete now assumes there is only one such rule!
dbainbri4d3a0dc2020-12-02 00:33:42 +00001762 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset untagged rule to default", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001763 "device-id": oFsm.deviceID})
1764 sliceEvtocdRule := make([]uint8, 16)
1765 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1766 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1767 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1768 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1769 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00001770
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001771 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1772 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
1773 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1774 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1775 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00001776
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001777 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1778 0<<cTreatTTROffset| // Do not pop any tags
1779 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1780 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1781 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
mpagenko01e726e2020-10-23 09:45:29 +00001782
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001783 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1784 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
1785 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1786 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
mpagenko01e726e2020-10-23 09:45:29 +00001787
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001788 meParams := me.ParamData{
1789 EntityID: oFsm.evtocdID,
1790 Attributes: me.AttributeValueMap{
1791 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1792 },
1793 }
1794 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(context.TODO(), ConstDefaultOmciTimeout, true,
1795 oFsm.pAdaptFsm.commChan, meParams)
1796 //accept also nil as (error) return value for writing to LastTx
1797 // - this avoids misinterpretation of new received OMCI messages
1798 oFsm.pLastTxMeInstance = meInstance
1799
1800 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001801 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001802 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001803 logger.Errorw(ctx, "Evtocd reset untagged rule to default failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001804 log.Fields{"device-id": oFsm.deviceID})
1805 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1806 return
1807 }
1808 } // just for local var's
1809 { // just for local var's
1810 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00001811 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD delete priotagged rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001812 "device-id": oFsm.deviceID})
1813 sliceEvtocdRule := make([]uint8, 16)
1814 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1815 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1816 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1817 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1818 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1819
1820 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1821 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
1822 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
1823 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1824 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1825
1826 // delete indication for the indicated Filter
1827 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
1828 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
1829
1830 meParams := me.ParamData{
1831 EntityID: oFsm.evtocdID,
1832 Attributes: me.AttributeValueMap{
1833 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1834 },
1835 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001836 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001837 oFsm.pAdaptFsm.commChan, meParams)
1838 //accept also nil as (error) return value for writing to LastTx
1839 // - this avoids misinterpretation of new received OMCI messages
1840 oFsm.pLastTxMeInstance = meInstance
1841
1842 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001843 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001844 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001845 logger.Errorw(ctx, "Evtocd delete priotagged rule failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001846 log.Fields{"device-id": oFsm.deviceID})
1847 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1848 return
1849 }
mpagenko01e726e2020-10-23 09:45:29 +00001850 }
1851 } //just for local var's
1852 }
1853 }
1854
mpagenkofc4f56e2020-11-04 17:17:49 +00001855 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001856 logger.Debugw(ctx, "EVTOCD filter remove loop finished", log.Fields{"device-id": oFsm.deviceID})
Girish Gowdra26a40922021-01-29 17:14:34 -08001857 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRemFlowDone, aRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00001858}
1859
dbainbri4d3a0dc2020-12-02 00:33:42 +00001860func (oFsm *UniVlanConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenkodff5dda2020-08-28 11:52:01 +00001861 select {
Himani Chawla26e555c2020-08-31 12:30:20 +05301862 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenkodff5dda2020-08-28 11:52:01 +00001863 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00001864 // logger.Infow(ctx,"LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001865 case <-time.After(30 * time.Second): //AS FOR THE OTHER OMCI FSM's
dbainbri4d3a0dc2020-12-02 00:33:42 +00001866 logger.Warnw(ctx, "UniVlanConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001867 return fmt.Errorf("uniVlanConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00001868 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05301869 if success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001870 logger.Debug(ctx, "UniVlanConfigFsm multi entity response received")
mpagenkodff5dda2020-08-28 11:52:01 +00001871 return nil
1872 }
1873 // should not happen so far
dbainbri4d3a0dc2020-12-02 00:33:42 +00001874 logger.Warnw(ctx, "UniVlanConfigFsm multi entity response error", log.Fields{"for device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001875 return fmt.Errorf("uniVlanConfigFsm multi entity responseError %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00001876 }
1877}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001878
mpagenko551a4d42020-12-08 18:09:20 +00001879func (oFsm *UniVlanConfigFsm) performSettingMulticastME(ctx context.Context, tpID uint8, multicastGemPortID uint16, vlanID uint32) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001880 logger.Debugw(ctx, "Setting Multicast MEs", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001881 "multicastGemPortID": multicastGemPortID, "vlanID": vlanID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001882 errCreateMOP := oFsm.performCreatingMulticastOperationProfile(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001883 if errCreateMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001884 logger.Errorw(ctx, "MulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001885 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001886 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001887 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMOP)
1888 }
1889
dbainbri4d3a0dc2020-12-02 00:33:42 +00001890 errSettingMOP := oFsm.performSettingMulticastOperationProfile(ctx, multicastGemPortID, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001891 if errSettingMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001892 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001893 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001894 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001895 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errSettingMOP)
1896 }
1897
dbainbri4d3a0dc2020-12-02 00:33:42 +00001898 errCreateMSCI := oFsm.performCreatingMulticastSubscriberConfigInfo(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001899 if errCreateMSCI != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001900 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001901 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001902 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001903 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMSCI)
1904 }
1905
1906 meParams := me.ParamData{
1907 EntityID: macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo),
1908 Attributes: me.AttributeValueMap{
1909 "BridgeIdPointer": macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo),
1910 "PortNum": 0xf0, //fixed unique ANI side indication
1911 "TpType": 6, //MCGemIWTP
1912 "TpPointer": multicastGemPortID,
1913 },
1914 }
1915 meInstance := oFsm.pOmciCC.sendCreateMBPConfigDataVar(context.TODO(), ConstDefaultOmciTimeout, true,
1916 oFsm.pAdaptFsm.commChan, meParams)
1917 //accept also nil as (error) return value for writing to LastTx
1918 // - this avoids misinterpretation of new received OMCI messages
1919 oFsm.pLastTxMeInstance = meInstance
dbainbri4d3a0dc2020-12-02 00:33:42 +00001920 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001921 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001922 logger.Errorw(ctx, "CreateMBPConfigData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001923 log.Fields{"device-id": oFsm.deviceID, "MBPConfigDataID": macBridgeServiceProfileEID})
mpagenko9a304ea2020-12-16 15:54:01 +00001924 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001925 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, err)
1926 }
1927
1928 // ==> Start creating VTFD for mcast vlan
1929
1930 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1931 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
1932 mcastVtfdID := macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo)
1933
dbainbri4d3a0dc2020-12-02 00:33:42 +00001934 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD for mcast", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001935 "EntitytId": strconv.FormatInt(int64(mcastVtfdID), 16), "mcastVlanID": vlanID,
1936 "in state": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
1937 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
1938
1939 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
1940 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
1941 // new vlan associated with a different TP.
1942 vtfdFilterList[0] = uint16(vlanID)