blob: 42a35f5610579b9c6c06acff12ff603811f1520f [file] [log] [blame]
mpagenkodff5dda2020-08-28 11:52:01 +00001/*
2 * Copyright 2020-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//Package adaptercoreonu provides the utility for onu devices, flows and statistics
18package adaptercoreonu
19
20import (
21 "context"
22 "encoding/binary"
Andrea Campanella6515c582020-10-05 11:25:00 +020023 "fmt"
ozgecanetsiab5000ef2020-11-27 14:38:20 +030024 "net"
mpagenkodff5dda2020-08-28 11:52:01 +000025 "strconv"
Holger Hildebrandt394c5522020-09-11 11:23:01 +000026 "sync"
mpagenkodff5dda2020-08-28 11:52:01 +000027 "time"
28
mpagenko01e726e2020-10-23 09:45:29 +000029 gp "github.com/google/gopacket"
mpagenkodff5dda2020-08-28 11:52:01 +000030 "github.com/looplab/fsm"
31 "github.com/opencord/omci-lib-go"
32 me "github.com/opencord/omci-lib-go/generated"
dbainbri4d3a0dc2020-12-02 00:33:42 +000033 "github.com/opencord/voltha-lib-go/v4/pkg/log"
34 of "github.com/opencord/voltha-protos/v4/go/openflow_13"
mpagenkodff5dda2020-08-28 11:52:01 +000035)
36
37const (
38 // internal predefined values
39 cDefaultDownstreamMode = 0
40 cDefaultTpid = 0x8100
mpagenko01e726e2020-10-23 09:45:29 +000041 cVtfdTableSize = 12 //as per G.988
42 cMaxAllowedFlows = cVtfdTableSize //which might be under discussion, for the moment connected to limit of VLAN's within VTFD
mpagenkodff5dda2020-08-28 11:52:01 +000043)
44
45const (
46 // bit mask offsets for EVTOCD VlanTaggingOperationTable related to 32 bits (4 bytes)
47 cFilterPrioOffset = 28
48 cFilterVidOffset = 15
49 cFilterTpidOffset = 12
50 cFilterEtherTypeOffset = 0
51 cTreatTTROffset = 30
52 cTreatPrioOffset = 16
53 cTreatVidOffset = 3
54 cTreatTpidOffset = 0
55)
56const (
57 // byte offsets for EVTOCD VlanTaggingOperationTable related to overall 16 byte size with slice byte 0 as first Byte (MSB)
58 cFilterOuterOffset = 0
59 cFilterInnerOffset = 4
60 cTreatOuterOffset = 8
61 cTreatInnerOffset = 12
62)
63const (
64 // basic values used within EVTOCD VlanTaggingOperationTable in respect to their bitfields
65 cPrioIgnoreTag uint32 = 15
66 cPrioDefaultFilter uint32 = 14
67 cPrioDoNotFilter uint32 = 8
68 cDoNotFilterVid uint32 = 4096
69 cDoNotFilterTPID uint32 = 0
70 cDoNotFilterEtherType uint32 = 0
71 cDoNotAddPrio uint32 = 15
72 cCopyPrioFromInner uint32 = 8
Himani Chawla4d908332020-08-31 12:30:20 +053073 //cDontCarePrio uint32 = 0
mpagenkodff5dda2020-08-28 11:52:01 +000074 cDontCareVid uint32 = 0
75 cDontCareTpid uint32 = 0
76 cSetOutputTpidCopyDei uint32 = 4
77)
78
79const (
80 // events of config PON ANI port FSM
mpagenko01e726e2020-10-23 09:45:29 +000081 vlanEvStart = "vlanEvStart"
82 vlanEvWaitTechProf = "vlanEvWaitTechProf"
83 vlanEvContinueConfig = "vlanEvContinueConfig"
84 vlanEvStartConfig = "vlanEvStartConfig"
85 vlanEvRxConfigVtfd = "vlanEvRxConfigVtfd"
86 vlanEvRxConfigEvtocd = "vlanEvRxConfigEvtocd"
mpagenko551a4d42020-12-08 18:09:20 +000087 vlanEvWaitTPIncr = "vlanEvWaitTPIncr"
mpagenko01e726e2020-10-23 09:45:29 +000088 vlanEvIncrFlowConfig = "vlanEvIncrFlowConfig"
mpagenkofc4f56e2020-11-04 17:17:49 +000089 vlanEvRenew = "vlanEvRenew"
mpagenko01e726e2020-10-23 09:45:29 +000090 vlanEvRemFlowConfig = "vlanEvRemFlowConfig"
91 vlanEvRemFlowDone = "vlanEvRemFlowDone"
92 vlanEvFlowDataRemoved = "vlanEvFlowDataRemoved"
Holger Hildebrandt394c5522020-09-11 11:23:01 +000093 //vlanEvTimeoutSimple = "vlanEvTimeoutSimple"
94 //vlanEvTimeoutMids = "vlanEvTimeoutMids"
Himani Chawla4d908332020-08-31 12:30:20 +053095 vlanEvReset = "vlanEvReset"
96 vlanEvRestart = "vlanEvRestart"
mpagenkodff5dda2020-08-28 11:52:01 +000097)
mpagenko01e726e2020-10-23 09:45:29 +000098
mpagenkodff5dda2020-08-28 11:52:01 +000099const (
100 // states of config PON ANI port FSM
101 vlanStDisabled = "vlanStDisabled"
102 vlanStStarting = "vlanStStarting"
103 vlanStWaitingTechProf = "vlanStWaitingTechProf"
104 vlanStConfigVtfd = "vlanStConfigVtfd"
105 vlanStConfigEvtocd = "vlanStConfigEvtocd"
106 vlanStConfigDone = "vlanStConfigDone"
mpagenko551a4d42020-12-08 18:09:20 +0000107 vlanStIncrFlowWaitTP = "vlanStIncrFlowWaitTP"
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000108 vlanStConfigIncrFlow = "vlanStConfigIncrFlow"
mpagenko01e726e2020-10-23 09:45:29 +0000109 vlanStRemoveFlow = "vlanStRemoveFlow"
mpagenkodff5dda2020-08-28 11:52:01 +0000110 vlanStCleanupDone = "vlanStCleanupDone"
111 vlanStResetting = "vlanStResetting"
112)
113
mpagenko01e726e2020-10-23 09:45:29 +0000114type uniVlanRuleParams struct {
mpagenko551a4d42020-12-08 18:09:20 +0000115 TpID uint8 `json:"tp_id"`
mpagenko01e726e2020-10-23 09:45:29 +0000116 MatchVid uint32 `json:"match_vid"` //use uint32 types for allowing immediate bitshifting
117 MatchPcp uint32 `json:"match_pcp"`
118 TagsToRemove uint32 `json:"tags_to_remove"`
119 SetVid uint32 `json:"set_vid"`
120 SetPcp uint32 `json:"set_pcp"`
121}
122
123type uniVlanFlowParams struct {
124 CookieSlice []uint64 `json:"cookie_slice"`
125 VlanRuleParams uniVlanRuleParams `json:"vlan_rule_params"`
126}
127
128type uniRemoveVlanFlowParams struct {
129 cookie uint64 //just the last cookie valid for removal
130 vlanRuleParams uniVlanRuleParams
131}
132
mpagenkodff5dda2020-08-28 11:52:01 +0000133//UniVlanConfigFsm defines the structure for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
134type UniVlanConfigFsm struct {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530135 pDeviceHandler *deviceHandler
mpagenko01e726e2020-10-23 09:45:29 +0000136 deviceID string
Himani Chawla6d2ae152020-09-02 13:11:20 +0530137 pOmciCC *omciCC
138 pOnuUniPort *onuUniPort
139 pUniTechProf *onuUniTechProf
140 pOnuDB *onuDeviceDB
mpagenkodff5dda2020-08-28 11:52:01 +0000141 requestEvent OnuDeviceEvent
142 omciMIdsResponseReceived chan bool //seperate channel needed for checking multiInstance OMCI message responses
143 pAdaptFsm *AdapterFsm
144 acceptIncrementalEvtoOption bool
mpagenko2418ab02020-11-12 12:58:06 +0000145 clearPersistency bool
mpagenko551a4d42020-12-08 18:09:20 +0000146 mutexFlowParams sync.RWMutex
mpagenko9a304ea2020-12-16 15:54:01 +0000147 actualUniVlanConfigRule uniVlanRuleParams
mpagenko01e726e2020-10-23 09:45:29 +0000148 uniVlanFlowParamsSlice []uniVlanFlowParams
149 uniRemoveFlowsSlice []uniRemoveVlanFlowParams
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000150 numUniFlows uint8 // expected number of flows should be less than 12
151 configuredUniFlow uint8
mpagenko01e726e2020-10-23 09:45:29 +0000152 numRemoveFlows uint8
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000153 numVlanFilterEntries uint8
mpagenko01e726e2020-10-23 09:45:29 +0000154 vlanFilterList [cVtfdTableSize]uint16
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000155 evtocdID uint16
mpagenko01e726e2020-10-23 09:45:29 +0000156 pLastTxMeInstance *me.ManagedEntity
mpagenkofc4f56e2020-11-04 17:17:49 +0000157 requestEventOffset uint8
mpagenko551a4d42020-12-08 18:09:20 +0000158 TpIDWaitingFor uint8
mpagenkodff5dda2020-08-28 11:52:01 +0000159}
160
mpagenko01e726e2020-10-23 09:45:29 +0000161//NewUniVlanConfigFsm is the 'constructor' for the state machine to config the PON ANI ports
162// of ONU UNI ports via OMCI
dbainbri4d3a0dc2020-12-02 00:33:42 +0000163func NewUniVlanConfigFsm(ctx context.Context, apDeviceHandler *deviceHandler, apDevOmciCC *omciCC, apUniPort *onuUniPort,
mpagenko551a4d42020-12-08 18:09:20 +0000164 apUniTechProf *onuUniTechProf, apOnuDB *onuDeviceDB, aTechProfileID uint8,
mpagenko01e726e2020-10-23 09:45:29 +0000165 aRequestEvent OnuDeviceEvent, aName string, aCommChannel chan Message, aAcceptIncrementalEvto bool,
166 aCookieSlice []uint64, aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) *UniVlanConfigFsm {
mpagenkodff5dda2020-08-28 11:52:01 +0000167 instFsm := &UniVlanConfigFsm{
168 pDeviceHandler: apDeviceHandler,
mpagenko01e726e2020-10-23 09:45:29 +0000169 deviceID: apDeviceHandler.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +0000170 pOmciCC: apDevOmciCC,
171 pOnuUniPort: apUniPort,
172 pUniTechProf: apUniTechProf,
173 pOnuDB: apOnuDB,
mpagenkodff5dda2020-08-28 11:52:01 +0000174 requestEvent: aRequestEvent,
175 acceptIncrementalEvtoOption: aAcceptIncrementalEvto,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000176 numUniFlows: 0,
177 configuredUniFlow: 0,
mpagenko01e726e2020-10-23 09:45:29 +0000178 numRemoveFlows: 0,
mpagenko2418ab02020-11-12 12:58:06 +0000179 clearPersistency: true,
mpagenkodff5dda2020-08-28 11:52:01 +0000180 }
181
mpagenko01e726e2020-10-23 09:45:29 +0000182 instFsm.pAdaptFsm = NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
mpagenkodff5dda2020-08-28 11:52:01 +0000183 if instFsm.pAdaptFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000184 logger.Errorw(ctx, "UniVlanConfigFsm's AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000185 "device-id": instFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000186 return nil
187 }
mpagenkodff5dda2020-08-28 11:52:01 +0000188 instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
189 vlanStDisabled,
190 fsm.Events{
191 {Name: vlanEvStart, Src: []string{vlanStDisabled}, Dst: vlanStStarting},
192 {Name: vlanEvWaitTechProf, Src: []string{vlanStStarting}, Dst: vlanStWaitingTechProf},
193 {Name: vlanEvContinueConfig, Src: []string{vlanStWaitingTechProf}, Dst: vlanStConfigVtfd},
194 {Name: vlanEvStartConfig, Src: []string{vlanStStarting}, Dst: vlanStConfigVtfd},
195 {Name: vlanEvRxConfigVtfd, Src: []string{vlanStConfigVtfd}, Dst: vlanStConfigEvtocd},
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000196 {Name: vlanEvRxConfigEvtocd, Src: []string{vlanStConfigEvtocd, vlanStConfigIncrFlow},
197 Dst: vlanStConfigDone},
mpagenko551a4d42020-12-08 18:09:20 +0000198 {Name: vlanEvRenew, Src: []string{vlanStConfigDone}, Dst: vlanStStarting},
199 {Name: vlanEvWaitTPIncr, Src: []string{vlanStConfigDone}, Dst: vlanStIncrFlowWaitTP},
200 {Name: vlanEvIncrFlowConfig, Src: []string{vlanStConfigDone, vlanStIncrFlowWaitTP},
201 Dst: vlanStConfigIncrFlow},
mpagenko01e726e2020-10-23 09:45:29 +0000202 {Name: vlanEvRemFlowConfig, Src: []string{vlanStConfigDone}, Dst: vlanStRemoveFlow},
203 {Name: vlanEvRemFlowDone, Src: []string{vlanStRemoveFlow}, Dst: vlanStCleanupDone},
204 {Name: vlanEvFlowDataRemoved, Src: []string{vlanStCleanupDone}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000205 /*
206 {Name: vlanEvTimeoutSimple, Src: []string{
207 vlanStCreatingDot1PMapper, vlanStCreatingMBPCD, vlanStSettingTconts, vlanStSettingDot1PMapper}, Dst: vlanStStarting},
208 {Name: vlanEvTimeoutMids, Src: []string{
209 vlanStCreatingGemNCTPs, vlanStCreatingGemIWs, vlanStSettingPQs}, Dst: vlanStStarting},
210 */
211 // exceptional treatment for all states except vlanStResetting
212 {Name: vlanEvReset, Src: []string{vlanStStarting, vlanStWaitingTechProf,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000213 vlanStConfigVtfd, vlanStConfigEvtocd, vlanStConfigDone, vlanStConfigIncrFlow,
mpagenko01e726e2020-10-23 09:45:29 +0000214 vlanStRemoveFlow, vlanStCleanupDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000215 Dst: vlanStResetting},
216 // the only way to get to resource-cleared disabled state again is via "resseting"
217 {Name: vlanEvRestart, Src: []string{vlanStResetting}, Dst: vlanStDisabled},
218 },
mpagenkodff5dda2020-08-28 11:52:01 +0000219 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000220 "enter_state": func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(ctx, e) },
221 "enter_" + vlanStStarting: func(e *fsm.Event) { instFsm.enterConfigStarting(ctx, e) },
222 "enter_" + vlanStConfigVtfd: func(e *fsm.Event) { instFsm.enterConfigVtfd(ctx, e) },
223 "enter_" + vlanStConfigEvtocd: func(e *fsm.Event) { instFsm.enterConfigEvtocd(ctx, e) },
224 "enter_" + vlanStConfigDone: func(e *fsm.Event) { instFsm.enterVlanConfigDone(ctx, e) },
225 "enter_" + vlanStConfigIncrFlow: func(e *fsm.Event) { instFsm.enterConfigIncrFlow(ctx, e) },
226 "enter_" + vlanStRemoveFlow: func(e *fsm.Event) { instFsm.enterRemoveFlow(ctx, e) },
227 "enter_" + vlanStCleanupDone: func(e *fsm.Event) { instFsm.enterVlanCleanupDone(ctx, e) },
228 "enter_" + vlanStResetting: func(e *fsm.Event) { instFsm.enterResetting(ctx, e) },
229 "enter_" + vlanStDisabled: func(e *fsm.Event) { instFsm.enterDisabled(ctx, e) },
mpagenkodff5dda2020-08-28 11:52:01 +0000230 },
231 )
232 if instFsm.pAdaptFsm.pFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000233 logger.Errorw(ctx, "UniVlanConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000234 "device-id": instFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000235 return nil
236 }
237
dbainbri4d3a0dc2020-12-02 00:33:42 +0000238 _ = instFsm.initUniFlowParams(ctx, aTechProfileID, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000239
dbainbri4d3a0dc2020-12-02 00:33:42 +0000240 logger.Debugw(ctx, "UniVlanConfigFsm created", log.Fields{"device-id": instFsm.deviceID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000241 "accIncrEvto": instFsm.acceptIncrementalEvtoOption})
mpagenkodff5dda2020-08-28 11:52:01 +0000242 return instFsm
243}
244
mpagenko01e726e2020-10-23 09:45:29 +0000245//initUniFlowParams is a simplified form of SetUniFlowParams() used for first flow parameters configuration
mpagenko551a4d42020-12-08 18:09:20 +0000246func (oFsm *UniVlanConfigFsm) initUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +0000247 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) error {
248 loRuleParams := uniVlanRuleParams{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000249 TpID: aTpID,
250 MatchVid: uint32(aMatchVlan),
251 SetVid: uint32(aSetVlan),
252 SetPcp: uint32(aSetPcp),
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000253 }
254 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
mpagenko01e726e2020-10-23 09:45:29 +0000255 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
256 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000257
mpagenko01e726e2020-10-23 09:45:29 +0000258 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000259 //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 +0000260 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000261 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
262 } else {
263 if !oFsm.acceptIncrementalEvtoOption {
264 //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 +0000265 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000266 }
267 }
268
mpagenko01e726e2020-10-23 09:45:29 +0000269 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000270 // no prio/vid filtering requested
mpagenko01e726e2020-10-23 09:45:29 +0000271 loRuleParams.TagsToRemove = 0 //no tag pop action
272 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
273 if loRuleParams.SetPcp == cCopyPrioFromInner {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000274 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
275 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
276 // might collide with NoMatchVid/CopyPrio(/setVid) setting
277 // this was some precondition setting taken over from py adapter ..
mpagenko01e726e2020-10-23 09:45:29 +0000278 loRuleParams.SetPcp = 0
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000279 }
280 }
mpagenko01e726e2020-10-23 09:45:29 +0000281
282 loFlowParams := uniVlanFlowParams{VlanRuleParams: loRuleParams}
283 loFlowParams.CookieSlice = make([]uint64, 0)
284 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
285
286 //no mutex protection is required for initial access and adding the first flow is always possible
287 oFsm.uniVlanFlowParamsSlice = make([]uniVlanFlowParams, 0)
288 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000289 logger.Debugw(ctx, "first UniVlanConfigFsm flow added", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000290 "Cookies": oFsm.uniVlanFlowParamsSlice[0].CookieSlice,
291 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
292 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
293 "SetPcp": loRuleParams.SetPcp,
294 "device-id": oFsm.deviceID})
295 oFsm.numUniFlows = 1
296 oFsm.uniRemoveFlowsSlice = make([]uniRemoveVlanFlowParams, 0) //initially nothing to remove
297
298 //permanently store flow config for reconcile case
dbainbri4d3a0dc2020-12-02 00:33:42 +0000299 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
mpagenko01e726e2020-10-23 09:45:29 +0000300 &oFsm.uniVlanFlowParamsSlice); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000301 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000302 return err
303 }
304
305 return nil
306}
307
mpagenko551a4d42020-12-08 18:09:20 +0000308//GetWaitingTpID returns the TpId that the FSM might be waiting for continuation (0 if none)
309func (oFsm *UniVlanConfigFsm) GetWaitingTpID() uint8 {
310 //mutex protection is required for possible concurrent access to FSM members
311 oFsm.mutexFlowParams.RLock()
312 defer oFsm.mutexFlowParams.RUnlock()
313 return oFsm.TpIDWaitingFor
314}
315
mpagenko2418ab02020-11-12 12:58:06 +0000316//RequestClearPersistency sets the internal flag to not clear persistency data (false=NoClear)
317func (oFsm *UniVlanConfigFsm) RequestClearPersistency(aClear bool) {
318 //mutex protection is required for possible concurrent access to FSM members
mpagenko551a4d42020-12-08 18:09:20 +0000319 oFsm.mutexFlowParams.RLock()
320 defer oFsm.mutexFlowParams.RUnlock()
mpagenko2418ab02020-11-12 12:58:06 +0000321 oFsm.clearPersistency = aClear
322}
323
mpagenko01e726e2020-10-23 09:45:29 +0000324//SetUniFlowParams verifies on existence of flow parameters to be configured,
325// optionally udates the cookie list or appends a new flow if there is space
326// if possible the FSM is trigggerd to start with the processing
mpagenko551a4d42020-12-08 18:09:20 +0000327// ignore complexity by now
328// nolint: gocyclo
329func (oFsm *UniVlanConfigFsm) SetUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +0000330 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) error {
331 loRuleParams := uniVlanRuleParams{
332 TpID: aTpID,
333 MatchVid: uint32(aMatchVlan),
334 SetVid: uint32(aSetVlan),
335 SetPcp: uint32(aSetPcp),
336 }
337 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
338 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
339 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
340
341 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
342 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
343 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
344 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
345 } else {
346 if !oFsm.acceptIncrementalEvtoOption {
347 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
348 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
349 }
350 }
351
352 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
353 // no prio/vid filtering requested
354 loRuleParams.TagsToRemove = 0 //no tag pop action
355 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
356 if loRuleParams.SetPcp == cCopyPrioFromInner {
357 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
358 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
359 // might collide with NoMatchVid/CopyPrio(/setVid) setting
360 // this was some precondition setting taken over from py adapter ..
361 loRuleParams.SetPcp = 0
362 }
363 }
364
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000365 flowEntryMatch := false
mpagenko01e726e2020-10-23 09:45:29 +0000366 flowCookieModify := false
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000367 //mutex protection is required for possible concurrent access to FSM members
368 oFsm.mutexFlowParams.Lock()
369 defer oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000370 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
371 //TODO: Verify if using e.g. hashes for the structures here for comparison may generate
372 // countable run time optimization (perhaps with including the hash in kvStore storage?)
373 if storedUniFlowParams.VlanRuleParams == loRuleParams {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000374 flowEntryMatch = true
dbainbri4d3a0dc2020-12-02 00:33:42 +0000375 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - rule already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000376 "device-id": oFsm.deviceID})
377 var cookieMatch bool
378 for _, newCookie := range aCookieSlice { // for all cookies available in the arguments
379 cookieMatch = false
380 for _, cookie := range storedUniFlowParams.CookieSlice {
381 if cookie == newCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000382 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - and cookie already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000383 "device-id": oFsm.deviceID, "cookie": cookie})
384 cookieMatch = true
385 break //found new cookie - no further search for this requested cookie
386 }
387 }
388 if !cookieMatch {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000389 logger.Debugw(ctx, "UniVlanConfigFsm flow setting -adding new cookie", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000390 "device-id": oFsm.deviceID, "cookie": newCookie})
391 //as range works with copies of the slice we have to write to the original slice!!
392 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
393 newCookie)
394 flowCookieModify = true
395 }
396 } //for all new cookies
397 break // found rule - no further rule search
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000398 }
399 }
mpagenko01e726e2020-10-23 09:45:29 +0000400 if !flowEntryMatch { //it is a new rule
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000401 if oFsm.numUniFlows < cMaxAllowedFlows {
mpagenko01e726e2020-10-23 09:45:29 +0000402 loFlowParams := uniVlanFlowParams{VlanRuleParams: loRuleParams}
403 loFlowParams.CookieSlice = make([]uint64, 0)
404 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
405 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000406 logger.Debugw(ctx, "UniVlanConfigFsm flow add", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000407 "Cookies": oFsm.uniVlanFlowParamsSlice[oFsm.numUniFlows].CookieSlice,
408 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
409 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
Girish Gowdra041dcb32020-11-16 16:54:30 -0800410 "SetPcp": loRuleParams.SetPcp, "numberofFlows": oFsm.numUniFlows + 1,
mpagenko01e726e2020-10-23 09:45:29 +0000411 "device-id": oFsm.deviceID})
412
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000413 oFsm.numUniFlows++
mpagenko01e726e2020-10-23 09:45:29 +0000414 // note: theoretical it would be possible to clear the same rule from the remove slice
415 // (for entries that have not yet been started with removal)
416 // but that is getting quite complicated - maybe a future optimization in case it should prove reasonable
417 // 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 +0000418
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000419 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
420 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
421 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
mpagenko551a4d42020-12-08 18:09:20 +0000422 if oFsm.configuredUniFlow == 0 {
423 // this is a restart with a complete new flow, we can re-use the initial flow config control
424 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenko9a304ea2020-12-16 15:54:01 +0000425 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +0000426 go func(a_pBaseFsm *fsm.FSM) {
427 _ = a_pBaseFsm.Event(vlanEvRenew)
428 }(pConfigVlanStateBaseFsm)
429 } else {
430 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000431 //store the actual rule that shall be worked upon in the following transient states
432 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +0000433 //tpId of the next rule to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000434 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko551a4d42020-12-08 18:09:20 +0000435 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, tpID)
436 oFsm.TpIDWaitingFor = tpID
mpagenko9a304ea2020-12-16 15:54:01 +0000437 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request (on setConfig)", log.Fields{
438 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
439 "set-Vlan": oFsm.actualUniVlanConfigRule.SetVid, "tp-id": tpID, "ProfDone": loTechProfDone})
440
mpagenko551a4d42020-12-08 18:09:20 +0000441 go func(aPBaseFsm *fsm.FSM, aTechProfDone bool) {
442 if aTechProfDone {
443 // let the vlan processing continue with next rule
444 _ = aPBaseFsm.Event(vlanEvIncrFlowConfig)
445 } else {
446 // set to waiting for Techprofile
447 _ = aPBaseFsm.Event(vlanEvWaitTPIncr)
448 }
449 }(pConfigVlanStateBaseFsm, loTechProfDone)
450 }
mpagenko01e726e2020-10-23 09:45:29 +0000451 } // if not in the appropriate state a new entry will be automatically considered later
452 // when the configDone state is reached
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000453 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000454 logger.Errorw(ctx, "UniVlanConfigFsm flow limit exceeded", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000455 "device-id": oFsm.deviceID, "flow-number": oFsm.numUniFlows})
456 return fmt.Errorf(" UniVlanConfigFsm flow limit exceeded %s", oFsm.deviceID)
457 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000458 } else {
459 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
460 if oFsm.numUniFlows == oFsm.configuredUniFlow {
461 //all requested rules really have been configured
462 // state transition notification is checked in deviceHandler
463 if oFsm.pDeviceHandler != nil {
464 //also the related TechProfile was already configured
dbainbri4d3a0dc2020-12-02 00:33:42 +0000465 logger.Debugw(ctx, "UniVlanConfigFsm rule already set - send immediate add-success event for reason update", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +0000466 "device-id": oFsm.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000467 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, oFsm.requestEvent)
mpagenkofc4f56e2020-11-04 17:17:49 +0000468 }
469 } else {
470 // avoid device reason update as the rule config connected to this flow may still be in progress
471 // and the device reason should only be updated on success of rule config
dbainbri4d3a0dc2020-12-02 00:33:42 +0000472 logger.Debugw(ctx, "UniVlanConfigFsm rule already set but configuration ongoing, suppress early add-success event for reason update",
mpagenkofc4f56e2020-11-04 17:17:49 +0000473 log.Fields{"device-id": oFsm.deviceID,
474 "NumberofRules": oFsm.numUniFlows, "Configured rules": oFsm.configuredUniFlow})
475 }
476 }
mpagenko01e726e2020-10-23 09:45:29 +0000477
478 if !flowEntryMatch || flowCookieModify { // some change was done to the flow entries
479 //permanently store flow config for reconcile case
dbainbri4d3a0dc2020-12-02 00:33:42 +0000480 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID, &oFsm.uniVlanFlowParamsSlice); err != nil {
481 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000482 return err
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000483 }
484 }
485 return nil
486}
487
mpagenko01e726e2020-10-23 09:45:29 +0000488//RemoveUniFlowParams verifies on existence of flow cookie,
489// if found removes cookie from flow cookie list and if this is empty
490// initiates removal of the flow related configuration from the ONU (via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000491func (oFsm *UniVlanConfigFsm) RemoveUniFlowParams(ctx context.Context, aCookie uint64) error {
mpagenko01e726e2020-10-23 09:45:29 +0000492 flowCookieMatch := false
493 //mutex protection is required for possible concurrent access to FSM members
494 oFsm.mutexFlowParams.Lock()
495 defer oFsm.mutexFlowParams.Unlock()
496 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
497 for i, cookie := range storedUniFlowParams.CookieSlice {
498 if cookie == aCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000499 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - cookie found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000500 "device-id": oFsm.deviceID, "cookie": cookie})
501 flowCookieMatch = true
502
503 //remove the cookie from the cookie slice and verify it is getting empty
504 if len(storedUniFlowParams.CookieSlice) == 1 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000505 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - full flow removal", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000506 "device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000507
508 //create a new element for the removeVlanFlow slice
509 loRemoveParams := uniRemoveVlanFlowParams{
510 vlanRuleParams: storedUniFlowParams.VlanRuleParams,
511 cookie: storedUniFlowParams.CookieSlice[0],
512 }
513 oFsm.uniRemoveFlowsSlice = append(oFsm.uniRemoveFlowsSlice, loRemoveParams)
514
515 //and remove the actual element from the addVlanFlow slice
516 // oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = nil //automatically done by garbage collector
517 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
518 oFsm.numUniFlows = 0 //no more flows
519 oFsm.configuredUniFlow = 0 //no more flows configured
520 oFsm.uniVlanFlowParamsSlice = nil //reset the slice
mpagenko2418ab02020-11-12 12:58:06 +0000521 //at this point it is evident that no flow anymore refers to a still possibly active Techprofile
522 //request that this profile gets deleted before a new flow add is allowed
mpagenko551a4d42020-12-08 18:09:20 +0000523 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, loRemoveParams.vlanRuleParams.TpID, true)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000524 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - no more flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000525 "device-id": oFsm.deviceID})
526 } else {
527 oFsm.numUniFlows--
528 if oFsm.configuredUniFlow > 0 {
529 oFsm.configuredUniFlow--
530 //TODO!! might be needed to consider still outstanding configure requests ..
531 // so a flow at removal might still not be configured !?!
532 }
mpagenko2418ab02020-11-12 12:58:06 +0000533 usedTpID := storedUniFlowParams.VlanRuleParams.TpID
mpagenko01e726e2020-10-23 09:45:29 +0000534 //cut off the requested flow by slicing out this element
535 oFsm.uniVlanFlowParamsSlice = append(
536 oFsm.uniVlanFlowParamsSlice[:flow], oFsm.uniVlanFlowParamsSlice[flow+1:]...)
mpagenko2418ab02020-11-12 12:58:06 +0000537 //here we have to check, if there are still other flows referencing to the actual ProfileId
538 // before we can request that this profile gets deleted before a new flow add is allowed
539 tpIDInOtherFlows := false
540 for _, tpUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
541 if tpUniFlowParams.VlanRuleParams.TpID == usedTpID {
542 tpIDInOtherFlows = true
543 break // search loop can be left
544 }
545 }
546 if tpIDInOtherFlows {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000547 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is still used in other flows", log.Fields{
mpagenko2418ab02020-11-12 12:58:06 +0000548 "device-id": oFsm.deviceID, "tp-id": usedTpID})
549 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000550 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is not used anymore", log.Fields{
mpagenko2418ab02020-11-12 12:58:06 +0000551 "device-id": oFsm.deviceID, "tp-id": usedTpID})
552 //request that this profile gets deleted before a new flow add is allowed
mpagenko551a4d42020-12-08 18:09:20 +0000553 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, usedTpID, true)
mpagenko2418ab02020-11-12 12:58:06 +0000554 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000555 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow removed from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000556 "device-id": oFsm.deviceID})
557 }
558 //trigger the FSM to remove the relevant rule
559 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
560 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
mpagenko9a304ea2020-12-16 15:54:01 +0000561 logger.Debugw(ctx, "UniVlanConfigFsm rule removal request", log.Fields{
562 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
563 "tp-id": loRemoveParams.vlanRuleParams.TpID,
564 "set-Vlan": loRemoveParams.vlanRuleParams.SetVid})
mpagenko01e726e2020-10-23 09:45:29 +0000565 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
mpagenko9a304ea2020-12-16 15:54:01 +0000566 // Can't call FSM Event directly, decoupling it
mpagenko01e726e2020-10-23 09:45:29 +0000567 go func(a_pBaseFsm *fsm.FSM) {
568 _ = a_pBaseFsm.Event(vlanEvRemFlowConfig)
569 }(pConfigVlanStateBaseFsm)
570 } // if not in the appropriate state a new entry will be automatically considered later
571 // when the configDone state is reached
572 } else {
mpagenko01e726e2020-10-23 09:45:29 +0000573 //cut off the requested cookie by slicing out this element
574 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(
575 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[:i],
576 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[i+1:]...)
mpagenkofc4f56e2020-11-04 17:17:49 +0000577 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
578 // state transition notification is checked in deviceHandler
579 if oFsm.pDeviceHandler != nil {
580 //making use of the add->remove successor enum assumption/definition
dbainbri4d3a0dc2020-12-02 00:33:42 +0000581 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(uint8(oFsm.requestEvent)+1))
mpagenkofc4f56e2020-11-04 17:17:49 +0000582 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000583 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - rule persists with still valid cookies", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000584 "device-id": oFsm.deviceID, "cookies": oFsm.uniVlanFlowParamsSlice[flow].CookieSlice})
585 }
586
587 //permanently store the modified flow config for reconcile case
mpagenkofc4f56e2020-11-04 17:17:49 +0000588 if oFsm.pDeviceHandler != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000589 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID, &oFsm.uniVlanFlowParamsSlice); err != nil {
590 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +0000591 return err
592 }
mpagenko01e726e2020-10-23 09:45:29 +0000593 }
594
595 break //found the cookie - no further search for this requested cookie
596 }
597 }
598 if flowCookieMatch { //cookie already found: no need for further search in other flows
599 break
600 }
601 } //search all flows
602 if !flowCookieMatch { //some cookie remove-request for a cookie that does not exist in the FSM data
dbainbri4d3a0dc2020-12-02 00:33:42 +0000603 logger.Warnw(ctx, "UniVlanConfigFsm flow removal - remove-cookie not found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000604 "device-id": oFsm.deviceID, "remove-cookie": aCookie})
605 // but accept the request with success as no such cookie (flow) does exist
mpagenkofc4f56e2020-11-04 17:17:49 +0000606 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
607 // state transition notification is checked in deviceHandler
608 if oFsm.pDeviceHandler != nil {
609 //making use of the add->remove successor enum assumption/definition
dbainbri4d3a0dc2020-12-02 00:33:42 +0000610 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(uint8(oFsm.requestEvent)+1))
mpagenkofc4f56e2020-11-04 17:17:49 +0000611 }
mpagenko01e726e2020-10-23 09:45:29 +0000612 return nil
613 } //unknown cookie
614
615 return nil
616}
617
dbainbri4d3a0dc2020-12-02 00:33:42 +0000618func (oFsm *UniVlanConfigFsm) enterConfigStarting(ctx context.Context, e *fsm.Event) {
619 logger.Debugw(ctx, "UniVlanConfigFsm start", log.Fields{"in state": e.FSM.Current(),
mpagenko01e726e2020-10-23 09:45:29 +0000620 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000621
622 // this FSM is not intended for re-start, needs always new creation for a new run
mpagenko01e726e2020-10-23 09:45:29 +0000623 // (self-destroying - compare enterDisabled())
mpagenkodff5dda2020-08-28 11:52:01 +0000624 oFsm.omciMIdsResponseReceived = make(chan bool)
625 // start go routine for processing of LockState messages
dbainbri4d3a0dc2020-12-02 00:33:42 +0000626 go oFsm.processOmciVlanMessages(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +0000627 //let the state machine run forward from here directly
628 pConfigVlanStateAFsm := oFsm.pAdaptFsm
629 if pConfigVlanStateAFsm != nil {
mpagenko551a4d42020-12-08 18:09:20 +0000630 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +0000631
632 //possibly the entry is not valid anymore based on intermediate delete requests
633 //just a basic protection ...
634 if len(oFsm.uniVlanFlowParamsSlice) == 0 {
635 oFsm.mutexFlowParams.Unlock()
636 logger.Debugw(ctx, "UniVlanConfigFsm start: no rule entry anymore available", log.Fields{
637 "device-id": oFsm.deviceID})
638 // Can't call FSM Event directly, decoupling it
639 go func(a_pAFsm *AdapterFsm) {
640 _ = a_pAFsm.pFsm.Event(vlanEvReset)
641 }(pConfigVlanStateAFsm)
642 return
643 }
644
645 //access to uniVlanFlowParamsSlice is done on first element only here per definition
646 //store the actual rule that shall be worked upon in the following transient states
647 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[0].VlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +0000648 oFsm.mutexFlowParams.Unlock()
mpagenko9a304ea2020-12-16 15:54:01 +0000649 tpID := oFsm.actualUniVlanConfigRule.TpID
650 oFsm.TpIDWaitingFor = tpID
mpagenko551a4d42020-12-08 18:09:20 +0000651 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID))
mpagenko9a304ea2020-12-16 15:54:01 +0000652 logger.Debugw(ctx, "UniVlanConfigFsm - start with first rule", log.Fields{
653 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
654 "set-Vlan": oFsm.actualUniVlanConfigRule.SetVid, "tp-id": tpID, "ProfDone": loTechProfDone})
mpagenko551a4d42020-12-08 18:09:20 +0000655 //cmp also usage in EVTOCDE create in omci_cc
656 oFsm.evtocdID = macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo)
mpagenko9a304ea2020-12-16 15:54:01 +0000657 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +0000658 go func(aPAFsm *AdapterFsm, aTechProfDone bool) {
659 if aPAFsm != nil && aPAFsm.pFsm != nil {
660 if aTechProfDone {
mpagenkodff5dda2020-08-28 11:52:01 +0000661 // let the vlan processing begin
mpagenko551a4d42020-12-08 18:09:20 +0000662 _ = aPAFsm.pFsm.Event(vlanEvStartConfig)
mpagenkodff5dda2020-08-28 11:52:01 +0000663 } else {
664 // set to waiting for Techprofile
mpagenko551a4d42020-12-08 18:09:20 +0000665 _ = aPAFsm.pFsm.Event(vlanEvWaitTechProf)
mpagenkodff5dda2020-08-28 11:52:01 +0000666 }
667 }
mpagenko551a4d42020-12-08 18:09:20 +0000668 }(pConfigVlanStateAFsm, loTechProfDone)
669 } else {
670 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
671 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
672 //should never happen, else: recovery would be needed from outside the FSM
673 return
mpagenkodff5dda2020-08-28 11:52:01 +0000674 }
675}
676
dbainbri4d3a0dc2020-12-02 00:33:42 +0000677func (oFsm *UniVlanConfigFsm) enterConfigVtfd(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000678 //mutex protection is required for possible concurrent access to FSM members
679 oFsm.mutexFlowParams.Lock()
mpagenko551a4d42020-12-08 18:09:20 +0000680 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
mpagenko9a304ea2020-12-16 15:54:01 +0000681 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +0000682 // meaning transparent setup - no specific VTFD setting required
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000683 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000684 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000685 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000686 // let the FSM proceed ... (from within this state all internal pointers may be expected to be correct)
mpagenkodff5dda2020-08-28 11:52:01 +0000687 pConfigVlanStateAFsm := oFsm.pAdaptFsm
mpagenko9a304ea2020-12-16 15:54:01 +0000688 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +0000689 go func(a_pAFsm *AdapterFsm) {
Himani Chawla4d908332020-08-31 12:30:20 +0530690 _ = a_pAFsm.pFsm.Event(vlanEvRxConfigVtfd)
mpagenkodff5dda2020-08-28 11:52:01 +0000691 }(pConfigVlanStateAFsm)
692 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300693 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
694 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
mpagenko9a304ea2020-12-16 15:54:01 +0000695 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + uint16(oFsm.actualUniVlanConfigRule.TpID)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000696 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300697 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000698 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
699 // setVid is assumed to be masked already by the caller to 12 bit
mpagenko9a304ea2020-12-16 15:54:01 +0000700 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000701 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000702 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000703 vtfdFilterList[0] = oFsm.vlanFilterList[0]
704 oFsm.numVlanFilterEntries = 1
mpagenkodff5dda2020-08-28 11:52:01 +0000705 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300706 EntityID: vtfdID,
mpagenkodff5dda2020-08-28 11:52:01 +0000707 Attributes: me.AttributeValueMap{
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000708 "VlanFilterList": vtfdFilterList, //omci lib wants a slice for serialization
709 "ForwardOperation": uint8(0x10), //VID investigation
710 "NumberOfEntries": oFsm.numVlanFilterEntries,
mpagenkodff5dda2020-08-28 11:52:01 +0000711 },
712 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000713 logger.Debugw(ctx, "UniVlanConfigFsm sendcreate VTFD", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000714 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000715 meInstance := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +0000716 oFsm.pAdaptFsm.commChan, meParams)
717 //accept also nil as (error) return value for writing to LastTx
718 // - this avoids misinterpretation of new received OMCI messages
719 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
720 // send shall return (dual format) error code that can be used here for immediate error treatment
721 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +0000722 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +0000723 }
724}
725
dbainbri4d3a0dc2020-12-02 00:33:42 +0000726func (oFsm *UniVlanConfigFsm) enterConfigEvtocd(ctx context.Context, e *fsm.Event) {
727 logger.Debugw(ctx, "UniVlanConfigFsm - start config EVTOCD loop", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000728 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +0000729 oFsm.requestEventOffset = 0 //0 offset for last flow-add activity
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300730 go func() {
mpagenko9a304ea2020-12-16 15:54:01 +0000731 //using the first element in the slice because it's the first flow per definition here
732 errEvto := oFsm.performConfigEvtocdEntries(ctx, 0)
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300733 //This is correct passing scenario
734 if errEvto == nil {
mpagenko9a304ea2020-12-16 15:54:01 +0000735 tpID := oFsm.actualUniVlanConfigRule.TpID
736 vlanID := oFsm.actualUniVlanConfigRule.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +0000737 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
738 logger.Infow(ctx, "Setting multicast MEs, with first flow", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300739 "techProfile": tpID, "gemPort": gemPort, "vlanID": vlanID, "configuredUniFlow": oFsm.configuredUniFlow})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000740 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300741 vlanID)
742 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000743 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300744 log.Fields{"device-id": oFsm.deviceID})
745 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
746 }
747 }
748 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
749 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
750 }
751 }()
mpagenkodff5dda2020-08-28 11:52:01 +0000752}
753
dbainbri4d3a0dc2020-12-02 00:33:42 +0000754func (oFsm *UniVlanConfigFsm) enterVlanConfigDone(ctx context.Context, e *fsm.Event) {
mpagenko9a304ea2020-12-16 15:54:01 +0000755 oFsm.mutexFlowParams.RLock()
756 defer oFsm.mutexFlowParams.RUnlock()
757
dbainbri4d3a0dc2020-12-02 00:33:42 +0000758 logger.Debugw(ctx, "UniVlanConfigFsm - checking on more flows", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +0000759 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
760 "overall-uni-rules": oFsm.numUniFlows, "configured-uni-rules": oFsm.configuredUniFlow})
761 pConfigVlanStateAFsm := oFsm.pAdaptFsm
762 if pConfigVlanStateAFsm == nil {
mpagenko551a4d42020-12-08 18:09:20 +0000763 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
764 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
765 //should never happen, else: recovery would be needed from outside the FSM
766 return
767 }
768 pConfigVlanStateBaseFsm := pConfigVlanStateAFsm.pFsm
mpagenko01e726e2020-10-23 09:45:29 +0000769 if len(oFsm.uniRemoveFlowsSlice) > 0 {
770 //some further flows are to be removed, removal always starts with the first element
mpagenko9a304ea2020-12-16 15:54:01 +0000771 logger.Debugw(ctx, "UniVlanConfigFsm rule removal from ConfigDone", log.Fields{
772 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
773 "tp-id": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.TpID,
774 "set-Vlan": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.SetVid})
775 // Can't call FSM Event directly, decoupling it
mpagenko01e726e2020-10-23 09:45:29 +0000776 go func(a_pBaseFsm *fsm.FSM) {
777 _ = a_pBaseFsm.Event(vlanEvRemFlowConfig)
778 }(pConfigVlanStateBaseFsm)
779 return
780 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000781 if oFsm.numUniFlows > oFsm.configuredUniFlow {
mpagenko551a4d42020-12-08 18:09:20 +0000782 if oFsm.configuredUniFlow == 0 {
mpagenko551a4d42020-12-08 18:09:20 +0000783 // this is a restart with a complete new flow, we can re-use the initial flow config control
784 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenko9a304ea2020-12-16 15:54:01 +0000785 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +0000786 go func(a_pBaseFsm *fsm.FSM) {
787 _ = a_pBaseFsm.Event(vlanEvRenew)
788 }(pConfigVlanStateBaseFsm)
789 return
790 }
791
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000792 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000793 //store the actual rule that shall be worked upon in the following transient states
794 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +0000795 //tpId of the next rule to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000796 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko551a4d42020-12-08 18:09:20 +0000797 oFsm.TpIDWaitingFor = tpID
mpagenko551a4d42020-12-08 18:09:20 +0000798 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, tpID)
mpagenko9a304ea2020-12-16 15:54:01 +0000799 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request", log.Fields{
800 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
801 "set-Vlan": oFsm.actualUniVlanConfigRule.SetVid, "tp-id": tpID, "ProfDone": loTechProfDone})
802 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +0000803 go func(aPBaseFsm *fsm.FSM, aTechProfDone bool) {
804 if aTechProfDone {
805 // let the vlan processing continue with next rule
806 _ = aPBaseFsm.Event(vlanEvIncrFlowConfig)
807 } else {
808 // set to waiting for Techprofile
809 _ = aPBaseFsm.Event(vlanEvWaitTPIncr)
810 }
811 }(pConfigVlanStateBaseFsm, loTechProfDone)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000812 return
813 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000814 logger.Debugw(ctx, "UniVlanConfigFsm - VLAN config done: send dh event notification", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000815 "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000816 // it might appear that some flows are requested also after 'flowPushed' event has been generated ...
817 // state transition notification is checked in deviceHandler
mpagenko551a4d42020-12-08 18:09:20 +0000818 // note: 'flowPushed' event is only generated if all 'pending' rules are configured
mpagenkodff5dda2020-08-28 11:52:01 +0000819 if oFsm.pDeviceHandler != nil {
mpagenkofc4f56e2020-11-04 17:17:49 +0000820 //making use of the add->remove successor enum assumption/definition
dbainbri4d3a0dc2020-12-02 00:33:42 +0000821 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(uint8(oFsm.requestEvent)+oFsm.requestEventOffset))
mpagenkodff5dda2020-08-28 11:52:01 +0000822 }
823}
824
dbainbri4d3a0dc2020-12-02 00:33:42 +0000825func (oFsm *UniVlanConfigFsm) enterConfigIncrFlow(ctx context.Context, e *fsm.Event) {
826 logger.Debugw(ctx, "UniVlanConfigFsm - start config further incremental flow", log.Fields{
Girish Gowdra041dcb32020-11-16 16:54:30 -0800827 "in state": e.FSM.Current(), "recent flow-number": oFsm.configuredUniFlow,
mpagenko01e726e2020-10-23 09:45:29 +0000828 "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000829 oFsm.mutexFlowParams.Lock()
mpagenko551a4d42020-12-08 18:09:20 +0000830 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000831
mpagenko9a304ea2020-12-16 15:54:01 +0000832 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000833 // meaning transparent setup - no specific VTFD setting required
834 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000835 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000836 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000837 } else {
838 if oFsm.numVlanFilterEntries == 0 {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300839 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
840 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
mpagenko9a304ea2020-12-16 15:54:01 +0000841 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + uint16(oFsm.actualUniVlanConfigRule.TpID)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000842 //no VTFD yet created
dbainbri4d3a0dc2020-12-02 00:33:42 +0000843 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300844 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000845 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300846 // 'SetVid' below is assumed to be masked already by the caller to 12 bit
mpagenko9a304ea2020-12-16 15:54:01 +0000847 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300848
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000849 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000850 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000851 vtfdFilterList[0] = oFsm.vlanFilterList[0]
852 oFsm.numVlanFilterEntries = 1
853 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300854 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000855 Attributes: me.AttributeValueMap{
856 "VlanFilterList": vtfdFilterList,
857 "ForwardOperation": uint8(0x10), //VID investigation
858 "NumberOfEntries": oFsm.numVlanFilterEntries,
859 },
860 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000861 meInstance := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000862 oFsm.pAdaptFsm.commChan, meParams)
863 //accept also nil as (error) return value for writing to LastTx
864 // - this avoids misinterpretation of new received OMCI messages
865 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
866 // send shall return (dual format) error code that can be used here for immediate error treatment
867 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +0000868 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000869 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300870 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
871 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
mpagenko551a4d42020-12-08 18:09:20 +0000872 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID +
mpagenko9a304ea2020-12-16 15:54:01 +0000873 uint16(oFsm.actualUniVlanConfigRule.TpID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300874
dbainbri4d3a0dc2020-12-02 00:33:42 +0000875 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300876 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000877 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000878 // setVid is assumed to be masked already by the caller to 12 bit
879 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] =
mpagenko9a304ea2020-12-16 15:54:01 +0000880 uint16(oFsm.actualUniVlanConfigRule.SetVid)
mpagenko01e726e2020-10-23 09:45:29 +0000881 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300882
883 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
884 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
885 // new vlan associated with a different TP.
mpagenko9a304ea2020-12-16 15:54:01 +0000886 vtfdFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300887 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000888
889 oFsm.numVlanFilterEntries++
890 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300891 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000892 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300893 "VlanFilterList": vtfdFilterList,
894 "ForwardOperation": uint8(0x10), //VID investigation
895 "NumberOfEntries": oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000896 },
897 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000898 meInstance := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000899 oFsm.pAdaptFsm.commChan, meParams)
900 //accept also nil as (error) return value for writing to LastTx
901 // - this avoids misinterpretation of new received OMCI messages
902 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
903 // send shall return (dual format) error code that can be used here for immediate error treatment
904 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +0000905 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000906 }
907 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +0000908 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000909 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000910 logger.Errorw(ctx, "VTFD create/set failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +0000911 log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +0000912 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
mpagenko9a304ea2020-12-16 15:54:01 +0000913 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +0000914 go func(a_pBaseFsm *fsm.FSM) {
915 _ = a_pBaseFsm.Event(vlanEvReset)
916 }(pConfigVlanStateBaseFsm)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000917 return
918 }
919 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000920 oFsm.requestEventOffset = 0 //0 offset for last flow-add activity
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300921 go func() {
mpagenko9a304ea2020-12-16 15:54:01 +0000922 tpID := oFsm.actualUniVlanConfigRule.TpID
dbainbri4d3a0dc2020-12-02 00:33:42 +0000923 errEvto := oFsm.performConfigEvtocdEntries(ctx, oFsm.configuredUniFlow)
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300924 //This is correct passing scenario
925 if errEvto == nil {
926 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
dbainbri4d3a0dc2020-12-02 00:33:42 +0000927 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
mpagenko9a304ea2020-12-16 15:54:01 +0000928 vlanID := oFsm.actualUniVlanConfigRule.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +0000929 logger.Infow(ctx, "Setting multicast MEs for additional flows", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300930 "techProfile": tpID, "gemPort": gemPort,
931 "vlanID": vlanID, "configuredUniFlow": oFsm.configuredUniFlow})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000932 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300933 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000934 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300935 log.Fields{"device-id": oFsm.deviceID})
936 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
937 }
938 }
939 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
940 }
941 }()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000942}
943
dbainbri4d3a0dc2020-12-02 00:33:42 +0000944func (oFsm *UniVlanConfigFsm) enterRemoveFlow(ctx context.Context, e *fsm.Event) {
mpagenko551a4d42020-12-08 18:09:20 +0000945 oFsm.mutexFlowParams.RLock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000946 logger.Debugw(ctx, "UniVlanConfigFsm - start removing the top remove-flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000947 "in state": e.FSM.Current(), "with last cookie": oFsm.uniRemoveFlowsSlice[0].cookie,
948 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000949
mpagenkofc4f56e2020-11-04 17:17:49 +0000950 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
951 loAllowSpecificOmciConfig := oFsm.pDeviceHandler.ReadyForSpecificOmciConfig
mpagenko01e726e2020-10-23 09:45:29 +0000952 loVlanEntryClear := uint8(0)
953 loVlanEntryRmPos := uint8(0x80) //with indication 'invalid' in bit 7
954 //shallow copy is sufficient as no reference variables are used within struct
955 loRuleParams := oFsm.uniRemoveFlowsSlice[0].vlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +0000956 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000957 logger.Debugw(ctx, "UniVlanConfigFsm - remove-flow parameters are", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000958 "match vid": loRuleParams.MatchVid, "match Pcp": loRuleParams.MatchPcp,
959 "set vid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
960 "device-id": oFsm.deviceID})
961
962 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
963 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +0000964 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD removal required for transparent flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000965 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
966 } else {
967 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization and 're-copy'
968 if oFsm.numVlanFilterEntries == 1 {
mpagenko551a4d42020-12-08 18:09:20 +0000969 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + uint16(loRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +0000970 //only one active VLAN entry (hopefully the SetVID we want to remove - should be, but not verified ..)
971 // so we can just delete the VTFD entry
dbainbri4d3a0dc2020-12-02 00:33:42 +0000972 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD delete (no more vlan filters)",
mpagenko01e726e2020-10-23 09:45:29 +0000973 log.Fields{"current vlan list": oFsm.vlanFilterList,
974 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +0000975 loVlanEntryClear = 1 //full VlanFilter clear request
976 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
dbainbri4d3a0dc2020-12-02 00:33:42 +0000977 meInstance := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300978 oFsm.pAdaptFsm.commChan, vtfdID)
mpagenkofc4f56e2020-11-04 17:17:49 +0000979 oFsm.pLastTxMeInstance = meInstance
980 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000981 logger.Debugw(ctx, "UniVlanConfigFsm delete VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000982 "device-id": oFsm.deviceID, "device-state": deviceReasonMap[oFsm.pDeviceHandler.deviceReason]})
mpagenkofc4f56e2020-11-04 17:17:49 +0000983 }
mpagenko01e726e2020-10-23 09:45:29 +0000984 } else {
985 //many VTFD already should exists - find and remove the one concerned by the actual remove rule
986 // by updating the VTFD per set command with new valid list
dbainbri4d3a0dc2020-12-02 00:33:42 +0000987 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD removal of requested VLAN from the list on OMCI",
mpagenko01e726e2020-10-23 09:45:29 +0000988 log.Fields{"current vlan list": oFsm.vlanFilterList,
989 "set-vlan": loRuleParams.SetVid, "device-id": oFsm.deviceID})
990 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
991 if loRuleParams.SetVid == uint32(oFsm.vlanFilterList[i]) {
992 loVlanEntryRmPos = i
993 break //abort search
994 }
995 }
996 if loVlanEntryRmPos < cVtfdTableSize {
mpagenko551a4d42020-12-08 18:09:20 +0000997 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + uint16(loRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +0000998 //valid entry was found - to be eclipsed
999 loVlanEntryClear = 2 //VlanFilter remove request for a specific entry
1000 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1001 if i < loVlanEntryRmPos {
1002 vtfdFilterList[i] = oFsm.vlanFilterList[i] //copy original
1003 } else if i < (cVtfdTableSize - 1) {
1004 vtfdFilterList[i] = oFsm.vlanFilterList[i+1] //copy successor (including 0 elements)
1005 } else {
1006 vtfdFilterList[i] = 0 //set last byte if needed
1007 }
1008 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001009 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001010 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001011 "new vlan list": vtfdFilterList, "device-id": oFsm.deviceID})
1012
mpagenkofc4f56e2020-11-04 17:17:49 +00001013 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001014 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
dbainbri4d3a0dc2020-12-02 00:33:42 +00001015 meInstance := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001016 oFsm.pAdaptFsm.commChan, vtfdID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001017 oFsm.pLastTxMeInstance = meInstance
1018 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001019 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001020 "device-id": oFsm.deviceID, "device-state": deviceReasonMap[oFsm.pDeviceHandler.deviceReason]})
mpagenko01e726e2020-10-23 09:45:29 +00001021 }
mpagenko01e726e2020-10-23 09:45:29 +00001022 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001023 logger.Warnw(ctx, "UniVlanConfigFsm: requested VLAN for removal not found in list - ignore and continue (no VTFD set)",
mpagenko01e726e2020-10-23 09:45:29 +00001024 log.Fields{"device-id": oFsm.deviceID})
1025 }
1026 }
1027 if loVlanEntryClear > 0 {
mpagenkofc4f56e2020-11-04 17:17:49 +00001028 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
1029 //waiting on response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001030 err := oFsm.waitforOmciResponse(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001031 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001032 logger.Errorw(ctx, "VTFD delete/reset failed, aborting VlanConfig FSM!",
mpagenkofc4f56e2020-11-04 17:17:49 +00001033 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001034 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001035 go func(a_pBaseFsm *fsm.FSM) {
1036 _ = a_pBaseFsm.Event(vlanEvReset)
1037 }(pConfigVlanStateBaseFsm)
1038 return
1039 }
mpagenko01e726e2020-10-23 09:45:29 +00001040 }
1041
1042 if loVlanEntryClear == 1 {
1043 oFsm.vlanFilterList[0] = 0 //first entry is the only that can contain the previous only-one element
1044 oFsm.numVlanFilterEntries = 0
1045 } else if loVlanEntryClear == 2 {
1046 // new VlanFilterList should be one entry smaller now - copy from last configured entry
1047 // this loop now includes the 0 element on previous last valid entry
1048 for i := uint8(0); i <= oFsm.numVlanFilterEntries; i++ {
1049 oFsm.vlanFilterList[i] = vtfdFilterList[i]
1050 }
1051 oFsm.numVlanFilterEntries--
1052 }
1053 }
1054 }
1055
mpagenkofc4f56e2020-11-04 17:17:49 +00001056 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001057 go oFsm.removeEvtocdEntries(ctx, loRuleParams)
mpagenkofc4f56e2020-11-04 17:17:49 +00001058 } else {
1059 // OMCI processing is not done, expectation is to have the ONU in some basic config state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001060 logger.Debugw(ctx, "UniVlanConfigFsm remove EVTOCD OMCI handling skipped based on device state", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +00001061 "device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001062 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001063 go func(a_pBaseFsm *fsm.FSM) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001064 _ = a_pBaseFsm.Event(vlanEvRemFlowDone, loRuleParams.TpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001065 }(pConfigVlanStateBaseFsm)
1066 }
mpagenkodff5dda2020-08-28 11:52:01 +00001067}
1068
dbainbri4d3a0dc2020-12-02 00:33:42 +00001069func (oFsm *UniVlanConfigFsm) enterVlanCleanupDone(ctx context.Context, e *fsm.Event) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001070 var tpID uint8
1071 // Extract the tpID
1072 if len(e.Args) > 0 {
1073 tpID = e.Args[0].(uint8)
1074 logger.Debugw(ctx, "UniVlanConfigFsm - flow removed for tp id", log.Fields{"device-id": oFsm.deviceID, "tpID": e.Args[0].(uint8)})
1075 } else {
1076 logger.Warnw(ctx, "UniVlanConfigFsm - tp id not available", log.Fields{"device-id": oFsm.deviceID})
1077 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001078 logger.Debugw(ctx, "UniVlanConfigFsm - removing the removal data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001079 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001080
mpagenko01e726e2020-10-23 09:45:29 +00001081 oFsm.mutexFlowParams.Lock()
1082 if len(oFsm.uniRemoveFlowsSlice) <= 1 {
1083 oFsm.uniRemoveFlowsSlice = nil //reset the slice
dbainbri4d3a0dc2020-12-02 00:33:42 +00001084 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - last remove-flow deleted", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001085 "device-id": oFsm.deviceID})
1086 } else {
1087 //cut off the actual flow by slicing out the first element
1088 oFsm.uniRemoveFlowsSlice = append(
1089 oFsm.uniRemoveFlowsSlice[:0],
1090 oFsm.uniRemoveFlowsSlice[1:]...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001091 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow deleted from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001092 "device-id": oFsm.deviceID})
1093 }
1094 oFsm.mutexFlowParams.Unlock()
1095
mpagenkofc4f56e2020-11-04 17:17:49 +00001096 oFsm.requestEventOffset = 1 //offset 1 for last flow-remove activity
mpagenko01e726e2020-10-23 09:45:29 +00001097 //return to the basic config verification state
mpagenkodff5dda2020-08-28 11:52:01 +00001098 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1099 if pConfigVlanStateAFsm != nil {
mpagenko9a304ea2020-12-16 15:54:01 +00001100 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +00001101 go func(a_pAFsm *AdapterFsm) {
1102 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001103 _ = a_pAFsm.pFsm.Event(vlanEvFlowDataRemoved)
mpagenkodff5dda2020-08-28 11:52:01 +00001104 }
1105 }(pConfigVlanStateAFsm)
1106 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001107
1108 oFsm.mutexFlowParams.RLock()
1109 noOfFlowRem := len(oFsm.uniRemoveFlowsSlice)
1110 oFsm.mutexFlowParams.RUnlock()
1111 // If all pending flow removes are completed and TP ID is valid, processing any pending TP delete
1112 if noOfFlowRem == 0 && tpID > 0 {
1113 logger.Debugw(ctx, "processing pending tp delete", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID})
1114 // If we are here then all flows are removed.
1115 oFsm.pDeviceHandler.ProcessPendingTpDelete(ctx, oFsm.pOnuUniPort, tpID)
1116 }
mpagenkodff5dda2020-08-28 11:52:01 +00001117}
1118
dbainbri4d3a0dc2020-12-02 00:33:42 +00001119func (oFsm *UniVlanConfigFsm) enterResetting(ctx context.Context, e *fsm.Event) {
1120 logger.Debugw(ctx, "UniVlanConfigFsm resetting", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001121
1122 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1123 if pConfigVlanStateAFsm != nil {
1124 // abort running message processing
1125 fsmAbortMsg := Message{
1126 Type: TestMsg,
1127 Data: TestMessage{
1128 TestMessageVal: AbortMessageProcessing,
1129 },
1130 }
1131 pConfigVlanStateAFsm.commChan <- fsmAbortMsg
1132
mpagenko9a304ea2020-12-16 15:54:01 +00001133 //try to restart the FSM to 'disabled'
1134 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +00001135 go func(a_pAFsm *AdapterFsm) {
1136 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301137 _ = a_pAFsm.pFsm.Event(vlanEvRestart)
mpagenkodff5dda2020-08-28 11:52:01 +00001138 }
1139 }(pConfigVlanStateAFsm)
1140 }
1141}
1142
dbainbri4d3a0dc2020-12-02 00:33:42 +00001143func (oFsm *UniVlanConfigFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
1144 logger.Debugw(ctx, "UniVlanConfigFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001145 oFsm.pLastTxMeInstance = nil
mpagenkodff5dda2020-08-28 11:52:01 +00001146 if oFsm.pDeviceHandler != nil {
mpagenko2418ab02020-11-12 12:58:06 +00001147 //TODO: to clarify with improved error treatment for VlanConfigFsm (timeout,reception) errors
1148 // current code removes the complete FSM including all flow/rule configuration done so far
1149 // this might be a bit to much, it would require fully new flow config from rwCore (at least on OnuDown/up)
1150 // maybe a more sophisticated approach is possible without clearing the data
mpagenko9a304ea2020-12-16 15:54:01 +00001151 oFsm.mutexFlowParams.RLock()
mpagenko2418ab02020-11-12 12:58:06 +00001152 if oFsm.clearPersistency {
1153 //permanently remove possibly stored persistent data
1154 if len(oFsm.uniVlanFlowParamsSlice) > 0 {
1155 var emptySlice = make([]uniVlanFlowParams, 0)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001156 _ = oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID, &emptySlice) //ignore errors
mpagenko2418ab02020-11-12 12:58:06 +00001157 }
1158 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001159 logger.Debugw(ctx, "UniVlanConfigFsm persistency data not cleared", log.Fields{"device-id": oFsm.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001160 }
mpagenko9a304ea2020-12-16 15:54:01 +00001161 oFsm.mutexFlowParams.RUnlock()
mpagenko2418ab02020-11-12 12:58:06 +00001162 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001163 go oFsm.pDeviceHandler.RemoveVlanFilterFsm(ctx, oFsm.pOnuUniPort)
mpagenkodff5dda2020-08-28 11:52:01 +00001164 }
1165}
1166
dbainbri4d3a0dc2020-12-02 00:33:42 +00001167func (oFsm *UniVlanConfigFsm) processOmciVlanMessages(ctx context.Context) { //ctx context.Context?
1168 logger.Debugw(ctx, "Start UniVlanConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001169loop:
1170 for {
mpagenkodff5dda2020-08-28 11:52:01 +00001171 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00001172 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001173 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +05301174 message, ok := <-oFsm.pAdaptFsm.commChan
1175 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001176 logger.Info(ctx, "UniVlanConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301177 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
1178 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1179 break loop
1180 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001181 logger.Debugw(ctx, "UniVlanConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301182
1183 switch message.Type {
1184 case TestMsg:
1185 msg, _ := message.Data.(TestMessage)
1186 if msg.TestMessageVal == AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001187 logger.Infow(ctx, "UniVlanConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001188 break loop
1189 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001190 logger.Warnw(ctx, "UniVlanConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Himani Chawla4d908332020-08-31 12:30:20 +05301191 case OMCI:
1192 msg, _ := message.Data.(OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001193 oFsm.handleOmciVlanConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301194 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001195 logger.Warn(ctx, "UniVlanConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301196 "message.Type": message.Type})
mpagenkodff5dda2020-08-28 11:52:01 +00001197 }
1198 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001199 logger.Infow(ctx, "End UniVlanConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001200}
1201
dbainbri4d3a0dc2020-12-02 00:33:42 +00001202func (oFsm *UniVlanConfigFsm) handleOmciVlanConfigMessage(ctx context.Context, msg OmciMessage) {
1203 logger.Debugw(ctx, "Rx OMCI UniVlanConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001204 "msgType": msg.OmciMsg.MessageType})
1205
1206 switch msg.OmciMsg.MessageType {
1207 case omci.CreateResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001208 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001209 if err := oFsm.handleOmciCreateResponseMessage(ctx, msg.OmciPacket); err != nil {
1210 logger.Warnw(ctx, "CreateResponse handling aborted", log.Fields{"err": err})
mpagenkodff5dda2020-08-28 11:52:01 +00001211 return
1212 }
mpagenkodff5dda2020-08-28 11:52:01 +00001213 } //CreateResponseType
1214 case omci.SetResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001215 { //leave that here as direct code as most often used
mpagenkodff5dda2020-08-28 11:52:01 +00001216 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1217 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001218 logger.Errorw(ctx, "Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001219 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001220 return
1221 }
1222 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1223 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001224 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001225 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001226 return
1227 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001228 logger.Debugw(ctx, "UniVlanConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkodff5dda2020-08-28 11:52:01 +00001229 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001230 logger.Errorw(ctx, "UniVlanConfigFsm Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001231 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
mpagenkodff5dda2020-08-28 11:52:01 +00001232 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1233 return
1234 }
mpagenko01e726e2020-10-23 09:45:29 +00001235 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1236 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1237 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001238 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "MulticastOperationsProfile":
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001239 { // let the MultiEntity config proceed by stopping the wait function
mpagenkodff5dda2020-08-28 11:52:01 +00001240 oFsm.omciMIdsResponseReceived <- true
1241 }
1242 }
1243 }
1244 } //SetResponseType
mpagenko01e726e2020-10-23 09:45:29 +00001245 case omci.DeleteResponseType:
1246 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001247 if err := oFsm.handleOmciDeleteResponseMessage(ctx, msg.OmciPacket); err != nil {
1248 logger.Warnw(ctx, "DeleteResponse handling aborted", log.Fields{"err": err})
mpagenko01e726e2020-10-23 09:45:29 +00001249 return
1250 }
1251 } //DeleteResponseType
mpagenkodff5dda2020-08-28 11:52:01 +00001252 default:
1253 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001254 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00001255 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001256 return
1257 }
1258 }
1259}
1260
dbainbri4d3a0dc2020-12-02 00:33:42 +00001261func (oFsm *UniVlanConfigFsm) handleOmciCreateResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00001262 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeCreateResponse)
1263 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001264 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001265 log.Fields{"device-id": oFsm.deviceID})
1266 return fmt.Errorf("omci msg layer could not be detected for CreateResponse for device-id %x",
1267 oFsm.deviceID)
1268 }
1269 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
1270 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001271 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001272 log.Fields{"device-id": oFsm.deviceID})
1273 return fmt.Errorf("omci msg layer could not be assigned for CreateResponse for device-id %x",
1274 oFsm.deviceID)
1275 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001276 logger.Debugw(ctx, "UniVlanConfigFsm CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001277 if msgObj.Result != me.Success && msgObj.Result != me.InstanceExists {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001278 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"device-id": oFsm.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00001279 "Error": msgObj.Result})
1280 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1281 return fmt.Errorf("omci CreateResponse Error for device-id %x",
1282 oFsm.deviceID)
1283 }
1284 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1285 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1286 // to satisfy StaticCodeAnalysis I had to move the small processing into a separate method :-(
1287 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001288 case "VlanTaggingFilterData", "MulticastOperationsProfile",
1289 "MulticastSubscriberConfigInfo", "MacBridgePortConfigurationData",
1290 "ExtendedVlanTaggingOperationConfigurationData":
mpagenko01e726e2020-10-23 09:45:29 +00001291 {
1292 if oFsm.pAdaptFsm.pFsm.Current() == vlanStConfigVtfd {
1293 // Only if CreateResponse is received from first flow entry - let the FSM proceed ...
1294 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigVtfd)
1295 } else { // let the MultiEntity config proceed by stopping the wait function
1296 oFsm.omciMIdsResponseReceived <- true
1297 }
1298 }
1299 }
1300 }
1301 return nil
1302}
1303
dbainbri4d3a0dc2020-12-02 00:33:42 +00001304func (oFsm *UniVlanConfigFsm) handleOmciDeleteResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00001305 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeDeleteResponse)
1306 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001307 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001308 log.Fields{"device-id": oFsm.deviceID})
1309 return fmt.Errorf("omci msg layer could not be detected for DeleteResponse for device-id %x",
1310 oFsm.deviceID)
1311 }
1312 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
1313 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001314 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001315 log.Fields{"device-id": oFsm.deviceID})
1316 return fmt.Errorf("omci msg layer could not be assigned for DeleteResponse for device-id %x",
1317 oFsm.deviceID)
1318 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001319 logger.Debugw(ctx, "UniVlanConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko01e726e2020-10-23 09:45:29 +00001320 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001321 logger.Errorw(ctx, "UniVlanConfigFsm - Omci DeleteResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001322 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1323 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1324 return fmt.Errorf("omci DeleteResponse Error for device-id %x",
1325 oFsm.deviceID)
1326 }
1327 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1328 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1329 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001330 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData":
mpagenko01e726e2020-10-23 09:45:29 +00001331 { // let the MultiEntity config proceed by stopping the wait function
1332 oFsm.omciMIdsResponseReceived <- true
1333 }
1334 }
1335 }
1336 return nil
1337}
1338
dbainbri4d3a0dc2020-12-02 00:33:42 +00001339func (oFsm *UniVlanConfigFsm) performConfigEvtocdEntries(ctx context.Context, aFlowEntryNo uint8) error {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001340 if aFlowEntryNo == 0 {
1341 // EthType set only at first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00001342 // EVTOCD ME is expected to exist at this point already from MIB-Download (with AssociationType/Pointer)
1343 // we need to extend the configuration by EthType definition and, to be sure, downstream 'inverse' mode
dbainbri4d3a0dc2020-12-02 00:33:42 +00001344 logger.Debugw(ctx, "UniVlanConfigFsm Tx Create::EVTOCD", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00001345 "EntitytId": strconv.FormatInt(int64(oFsm.evtocdID), 16),
1346 "i/oEthType": strconv.FormatInt(int64(cDefaultTpid), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001347 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001348 associationType := 2 // default to uniPPTP
1349 if oFsm.pOnuUniPort.portType == uniVEIP {
1350 associationType = 10
1351 }
1352 // Create the EVTOCD ME
mpagenkodff5dda2020-08-28 11:52:01 +00001353 meParams := me.ParamData{
1354 EntityID: oFsm.evtocdID,
1355 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001356 "AssociationType": uint8(associationType),
1357 "AssociatedMePointer": oFsm.pOnuUniPort.entityID,
mpagenkodff5dda2020-08-28 11:52:01 +00001358 },
1359 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001360 meInstance := oFsm.pOmciCC.sendCreateEvtocdVar(context.TODO(), ConstDefaultOmciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001361 oFsm.pAdaptFsm.commChan, meParams)
1362 //accept also nil as (error) return value for writing to LastTx
1363 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001364 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001365
1366 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001367 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001368 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001369 logger.Errorw(ctx, "Evtocd create failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001370 log.Fields{"device-id": oFsm.deviceID})
1371 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1372 return fmt.Errorf("evtocd create failed %s, error %s", oFsm.deviceID, err)
1373 }
1374
1375 // Set the EVTOCD ME default params
1376 meParams = me.ParamData{
1377 EntityID: oFsm.evtocdID,
1378 Attributes: me.AttributeValueMap{
1379 "InputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
1380 "OutputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
1381 "DownstreamMode": uint8(cDefaultDownstreamMode),
1382 },
1383 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001384 meInstance = oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001385 oFsm.pAdaptFsm.commChan, meParams)
1386 //accept also nil as (error) return value for writing to LastTx
1387 // - this avoids misinterpretation of new received OMCI messages
1388 oFsm.pLastTxMeInstance = meInstance
1389
1390 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001391 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001392 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001393 logger.Errorw(ctx, "Evtocd set TPID failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001394 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301395 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001396 return fmt.Errorf("evtocd set TPID failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00001397 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001398 } //first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00001399
mpagenko551a4d42020-12-08 18:09:20 +00001400 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001401 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00001402 //transparent transmission required
mpagenko551a4d42020-12-08 18:09:20 +00001403 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001404 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged transparent rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001405 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001406 sliceEvtocdRule := make([]uint8, 16)
1407 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1408 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1409 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1410 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1411 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1412
1413 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1414 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
1415 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1416 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1417 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1418
1419 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1420 0<<cTreatTTROffset| // Do not pop any tags
1421 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1422 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1423 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1424
1425 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1426 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
1427 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1428 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
1429
1430 meParams := me.ParamData{
1431 EntityID: oFsm.evtocdID,
1432 Attributes: me.AttributeValueMap{
1433 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1434 },
1435 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001436 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001437 oFsm.pAdaptFsm.commChan, meParams)
1438 //accept also nil as (error) return value for writing to LastTx
1439 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001440 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001441
1442 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001443 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001444 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001445 logger.Errorw(ctx, "Evtocd set transparent singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001446 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301447 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001448 return fmt.Errorf("evtocd set transparent singletagged rule failed %s, error %s", oFsm.deviceID, err)
1449
mpagenkodff5dda2020-08-28 11:52:01 +00001450 }
1451 } else {
1452 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
1453 if oFsm.acceptIncrementalEvtoOption {
mpagenko9a304ea2020-12-16 15:54:01 +00001454 matchPcp := oFsm.actualUniVlanConfigRule.MatchPcp
1455 matchVid := oFsm.actualUniVlanConfigRule.MatchVid
1456 setPcp := oFsm.actualUniVlanConfigRule.SetPcp
1457 setVid := oFsm.actualUniVlanConfigRule.SetVid
mpagenkodff5dda2020-08-28 11:52:01 +00001458 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001459 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged translation rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001460 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001461 sliceEvtocdRule := make([]uint8, 16)
1462 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1463 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1464 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1465 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1466 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1467
1468 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00001469 oFsm.actualUniVlanConfigRule.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
1470 oFsm.actualUniVlanConfigRule.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
mpagenkodff5dda2020-08-28 11:52:01 +00001471 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1472 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1473
1474 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00001475 oFsm.actualUniVlanConfigRule.TagsToRemove<<cTreatTTROffset| // either 1 or 0
mpagenkodff5dda2020-08-28 11:52:01 +00001476 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1477 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1478 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1479
1480 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00001481 oFsm.actualUniVlanConfigRule.SetPcp<<cTreatPrioOffset| // as configured in flow
1482 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| //as configured in flow
mpagenkodff5dda2020-08-28 11:52:01 +00001483 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00001484 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001485
1486 meParams := me.ParamData{
1487 EntityID: oFsm.evtocdID,
1488 Attributes: me.AttributeValueMap{
1489 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1490 },
1491 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001492 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001493 oFsm.pAdaptFsm.commChan, meParams)
1494 //accept also nil as (error) return value for writing to LastTx
1495 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001496 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001497
1498 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001499 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001500 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001501 logger.Errorw(ctx, "Evtocd set singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001502 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301503 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001504 return fmt.Errorf("evtocd set singletagged translation rule failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00001505 }
1506 } else {
1507 //not transparent and not acceptIncrementalEvtoOption untagged/priotagged->singletagged
1508 { // just for local var's
1509 // this defines stacking scenario: untagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00001510 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD untagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001511 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001512 sliceEvtocdRule := make([]uint8, 16)
1513 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1514 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1515 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1516 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1517 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1518
1519 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1520 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
1521 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1522 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1523 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1524
1525 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1526 0<<cTreatTTROffset| // Do not pop any tags
1527 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1528 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1529 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1530
1531 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1532 0<<cTreatPrioOffset| // vlan prio set to 0
1533 // (as done in Py code, maybe better option would be setPcp here, which still could be 0?)
mpagenko9a304ea2020-12-16 15:54:01 +00001534 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| // Outer VID don't care
mpagenkodff5dda2020-08-28 11:52:01 +00001535 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
1536
mpagenko551a4d42020-12-08 18:09:20 +00001537 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001538 meParams := me.ParamData{
1539 EntityID: oFsm.evtocdID,
1540 Attributes: me.AttributeValueMap{
1541 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1542 },
1543 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001544 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001545 oFsm.pAdaptFsm.commChan, meParams)
1546 //accept also nil as (error) return value for writing to LastTx
1547 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001548 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001549
1550 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001551 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001552 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001553 logger.Errorw(ctx, "Evtocd set untagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001554 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301555 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001556 return fmt.Errorf("evtocd set untagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
1557
mpagenkodff5dda2020-08-28 11:52:01 +00001558 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001559 } // just for local var's
mpagenkodff5dda2020-08-28 11:52:01 +00001560 { // just for local var's
1561 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00001562 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD priotagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001563 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001564 sliceEvtocdRule := make([]uint8, 16)
1565 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1566 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1567 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1568 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1569 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1570
1571 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1572 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
1573 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
1574 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1575 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1576
1577 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1578 1<<cTreatTTROffset| // pop the prio-tag
1579 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1580 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1581 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1582
mpagenko551a4d42020-12-08 18:09:20 +00001583 oFsm.mutexFlowParams.RLock()
mpagenkodff5dda2020-08-28 11:52:01 +00001584 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1585 cCopyPrioFromInner<<cTreatPrioOffset| // vlan copy from PrioTag
1586 // (as done in Py code, maybe better option would be setPcp here, which still could be PrioCopy?)
mpagenko9a304ea2020-12-16 15:54:01 +00001587 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| // Outer VID as configured
mpagenkodff5dda2020-08-28 11:52:01 +00001588 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00001589 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001590
1591 meParams := me.ParamData{
1592 EntityID: oFsm.evtocdID,
1593 Attributes: me.AttributeValueMap{
1594 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1595 },
1596 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001597 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001598 oFsm.pAdaptFsm.commChan, meParams)
1599 //accept also nil as (error) return value for writing to LastTx
1600 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001601 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001602
1603 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001604 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001605 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001606 logger.Errorw(ctx, "Evtocd set priotagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001607 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301608 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001609 return fmt.Errorf("evtocd set priotagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
1610
mpagenkodff5dda2020-08-28 11:52:01 +00001611 }
1612 } //just for local var's
1613 }
1614 }
1615
mpagenkofc4f56e2020-11-04 17:17:49 +00001616 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001617 logger.Debugw(ctx, "EVTOCD set loop finished", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001618 oFsm.configuredUniFlow++ // one (more) flow configured
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001619 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00001620}
1621
dbainbri4d3a0dc2020-12-02 00:33:42 +00001622func (oFsm *UniVlanConfigFsm) removeEvtocdEntries(ctx context.Context, aRuleParams uniVlanRuleParams) {
mpagenko01e726e2020-10-23 09:45:29 +00001623 // configured Input/Output TPID is not modified again - no influence if no filter is applied
1624 if aRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
1625 //transparent transmission was set
1626 //perhaps the config is not needed for removal,
1627 // but the specific InnerTpid setting is removed in favor of the real default forwarding rule
dbainbri4d3a0dc2020-12-02 00:33:42 +00001628 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset to default single tagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001629 "device-id": oFsm.deviceID})
1630 sliceEvtocdRule := make([]uint8, 16)
1631 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1632 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1633 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1634 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1635 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1636
1637 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1638 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
1639 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1640 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1641 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1642
1643 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1644 0<<cTreatTTROffset| // Do not pop any tags
1645 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1646 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1647 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1648
1649 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1650 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
1651 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1652 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
1653
1654 meParams := me.ParamData{
1655 EntityID: oFsm.evtocdID,
1656 Attributes: me.AttributeValueMap{
1657 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1658 },
1659 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001660 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00001661 oFsm.pAdaptFsm.commChan, meParams)
1662 //accept also nil as (error) return value for writing to LastTx
1663 // - this avoids misinterpretation of new received OMCI messages
1664 oFsm.pLastTxMeInstance = meInstance
1665
1666 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001667 err := oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001668 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001669 logger.Errorw(ctx, "Evtocd reset singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001670 log.Fields{"device-id": oFsm.deviceID})
1671 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1672 return
1673 }
1674 } else {
1675 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
1676 if oFsm.acceptIncrementalEvtoOption {
1677 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001678 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear single tagged translation rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001679 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
1680 sliceEvtocdRule := make([]uint8, 16)
1681 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1682 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1683 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1684 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1685 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1686
1687 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1688 aRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
1689 aRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
1690 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1691 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1692
1693 // delete indication for the indicated Filter
1694 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
1695 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
1696
1697 meParams := me.ParamData{
1698 EntityID: oFsm.evtocdID,
1699 Attributes: me.AttributeValueMap{
1700 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1701 },
1702 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001703 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00001704 oFsm.pAdaptFsm.commChan, meParams)
1705 //accept also nil as (error) return value for writing to LastTx
1706 // - this avoids misinterpretation of new received OMCI messages
1707 oFsm.pLastTxMeInstance = meInstance
1708
1709 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001710 err := oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001711 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001712 logger.Errorw(ctx, "Evtocd clear singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001713 log.Fields{"device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
1714 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1715 return
1716 }
1717 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001718 // VOL-3685
1719 // NOTE: With ALPHA ONUs it was seen that just resetting a particular entry in the EVTOCD table
1720 // and re-configuring a new entry would not work. The old entry is removed and new entry is created
1721 // indeed, but the traffic landing upstream would carry old vlan sometimes.
1722 // This is only a WORKAROUND which basically deletes the entire EVTOCD ME and re-creates it again
1723 // later when the flow is being re-installed.
1724 // Of course this is applicable to case only where single service (or single tcont) is in use and
1725 // there is only one service vlan (oFsm.acceptIncrementalEvtoOption is false in this case).
1726 // Interstingly this problem has not been observed in multi-tcont (or multi-service) scenario (in
1727 // which case the oFsm.acceptIncrementalEvtoOption is set to true).
1728 if oFsm.configuredUniFlow == 0 && !oFsm.acceptIncrementalEvtoOption {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001729 logger.Debugw(ctx, "UniVlanConfigFsm Tx Remove::EVTOCD", log.Fields{"device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001730 // When there are no more EVTOCD vlan configurations on the ONU and acceptIncrementalEvtoOption
1731 // is not enabled, delete the EVTOCD ME.
mpagenko01e726e2020-10-23 09:45:29 +00001732 meParams := me.ParamData{
1733 EntityID: oFsm.evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00001734 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001735 meInstance := oFsm.pOmciCC.sendDeleteEvtocd(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00001736 oFsm.pAdaptFsm.commChan, meParams)
1737 //accept also nil as (error) return value for writing to LastTx
1738 // - this avoids misinterpretation of new received OMCI messages
1739 oFsm.pLastTxMeInstance = meInstance
1740
1741 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001742 err := oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001743 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001744 logger.Errorw(ctx, "Evtocd delete rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001745 log.Fields{"device-id": oFsm.deviceID})
1746 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1747 return
1748 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001749 } else {
1750 // NOTE : We should ideally never ether this section when oFsm.acceptIncrementalEvtoOption is set to false
1751 // This is true for only ATT/DT workflow
dbainbri4d3a0dc2020-12-02 00:33:42 +00001752 logger.Debugw(ctx, "UniVlanConfigFsm: Remove EVTOCD set operation",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001753 log.Fields{"configured-flow": oFsm.configuredUniFlow, "incremental-evto": oFsm.acceptIncrementalEvtoOption})
1754 //not transparent and not acceptIncrementalEvtoOption: untagged/priotagged->singletagged
1755 { // just for local var's
1756 // this defines stacking scenario: untagged->singletagged
1757 //TODO!! in theory there could be different rules running in setting different PCP/VID'S
1758 // for untagged/priotagged, last rule wins (and remains the only one), maybe that should be
1759 // checked already at flow-add (and rejected) - to be observed if such is possible in Voltha
1760 // delete now assumes there is only one such rule!
dbainbri4d3a0dc2020-12-02 00:33:42 +00001761 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset untagged rule to default", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001762 "device-id": oFsm.deviceID})
1763 sliceEvtocdRule := make([]uint8, 16)
1764 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1765 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1766 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1767 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1768 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00001769
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001770 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1771 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
1772 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1773 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1774 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00001775
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001776 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1777 0<<cTreatTTROffset| // Do not pop any tags
1778 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1779 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1780 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
mpagenko01e726e2020-10-23 09:45:29 +00001781
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001782 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1783 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
1784 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1785 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
mpagenko01e726e2020-10-23 09:45:29 +00001786
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001787 meParams := me.ParamData{
1788 EntityID: oFsm.evtocdID,
1789 Attributes: me.AttributeValueMap{
1790 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1791 },
1792 }
1793 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(context.TODO(), ConstDefaultOmciTimeout, true,
1794 oFsm.pAdaptFsm.commChan, meParams)
1795 //accept also nil as (error) return value for writing to LastTx
1796 // - this avoids misinterpretation of new received OMCI messages
1797 oFsm.pLastTxMeInstance = meInstance
1798
1799 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001800 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001801 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001802 logger.Errorw(ctx, "Evtocd reset untagged rule to default failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001803 log.Fields{"device-id": oFsm.deviceID})
1804 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1805 return
1806 }
1807 } // just for local var's
1808 { // just for local var's
1809 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00001810 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD delete priotagged rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001811 "device-id": oFsm.deviceID})
1812 sliceEvtocdRule := make([]uint8, 16)
1813 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1814 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1815 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1816 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1817 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1818
1819 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1820 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
1821 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
1822 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1823 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1824
1825 // delete indication for the indicated Filter
1826 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
1827 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
1828
1829 meParams := me.ParamData{
1830 EntityID: oFsm.evtocdID,
1831 Attributes: me.AttributeValueMap{
1832 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1833 },
1834 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001835 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001836 oFsm.pAdaptFsm.commChan, meParams)
1837 //accept also nil as (error) return value for writing to LastTx
1838 // - this avoids misinterpretation of new received OMCI messages
1839 oFsm.pLastTxMeInstance = meInstance
1840
1841 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001842 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001843 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001844 logger.Errorw(ctx, "Evtocd delete priotagged rule failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001845 log.Fields{"device-id": oFsm.deviceID})
1846 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1847 return
1848 }
mpagenko01e726e2020-10-23 09:45:29 +00001849 }
1850 } //just for local var's
1851 }
1852 }
1853
mpagenkofc4f56e2020-11-04 17:17:49 +00001854 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001855 logger.Debugw(ctx, "EVTOCD filter remove loop finished", log.Fields{"device-id": oFsm.deviceID})
Girish Gowdra26a40922021-01-29 17:14:34 -08001856 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRemFlowDone, aRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00001857}
1858
dbainbri4d3a0dc2020-12-02 00:33:42 +00001859func (oFsm *UniVlanConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenkodff5dda2020-08-28 11:52:01 +00001860 select {
Himani Chawla26e555c2020-08-31 12:30:20 +05301861 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenkodff5dda2020-08-28 11:52:01 +00001862 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00001863 // logger.Infow(ctx,"LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001864 case <-time.After(30 * time.Second): //AS FOR THE OTHER OMCI FSM's
dbainbri4d3a0dc2020-12-02 00:33:42 +00001865 logger.Warnw(ctx, "UniVlanConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001866 return fmt.Errorf("uniVlanConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00001867 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05301868 if success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001869 logger.Debug(ctx, "UniVlanConfigFsm multi entity response received")
mpagenkodff5dda2020-08-28 11:52:01 +00001870 return nil
1871 }
1872 // should not happen so far
dbainbri4d3a0dc2020-12-02 00:33:42 +00001873 logger.Warnw(ctx, "UniVlanConfigFsm multi entity response error", log.Fields{"for device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001874 return fmt.Errorf("uniVlanConfigFsm multi entity responseError %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00001875 }
1876}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001877
mpagenko551a4d42020-12-08 18:09:20 +00001878func (oFsm *UniVlanConfigFsm) performSettingMulticastME(ctx context.Context, tpID uint8, multicastGemPortID uint16, vlanID uint32) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001879 logger.Debugw(ctx, "Setting Multicast MEs", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001880 "multicastGemPortID": multicastGemPortID, "vlanID": vlanID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001881 errCreateMOP := oFsm.performCreatingMulticastOperationProfile(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001882 if errCreateMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001883 logger.Errorw(ctx, "MulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001884 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001885 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001886 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMOP)
1887 }
1888
dbainbri4d3a0dc2020-12-02 00:33:42 +00001889 errSettingMOP := oFsm.performSettingMulticastOperationProfile(ctx, multicastGemPortID, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001890 if errSettingMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001891 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001892 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001893 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001894 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errSettingMOP)
1895 }
1896
dbainbri4d3a0dc2020-12-02 00:33:42 +00001897 errCreateMSCI := oFsm.performCreatingMulticastSubscriberConfigInfo(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001898 if errCreateMSCI != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001899 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001900 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001901 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001902 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMSCI)
1903 }
1904
1905 meParams := me.ParamData{
1906 EntityID: macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo),
1907 Attributes: me.AttributeValueMap{
1908 "BridgeIdPointer": macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo),
1909 "PortNum": 0xf0, //fixed unique ANI side indication
1910 "TpType": 6, //MCGemIWTP
1911 "TpPointer": multicastGemPortID,
1912 },
1913 }
1914 meInstance := oFsm.pOmciCC.sendCreateMBPConfigDataVar(context.TODO(), ConstDefaultOmciTimeout, true,
1915 oFsm.pAdaptFsm.commChan, meParams)
1916 //accept also nil as (error) return value for writing to LastTx
1917 // - this avoids misinterpretation of new received OMCI messages
1918 oFsm.pLastTxMeInstance = meInstance
dbainbri4d3a0dc2020-12-02 00:33:42 +00001919 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001920 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001921 logger.Errorw(ctx, "CreateMBPConfigData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001922 log.Fields{"device-id": oFsm.deviceID, "MBPConfigDataID": macBridgeServiceProfileEID})
mpagenko9a304ea2020-12-16 15:54:01 +00001923 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001924 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, err)
1925 }
1926
1927 // ==> Start creating VTFD for mcast vlan
1928
1929 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1930 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
1931 mcastVtfdID := macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo)
1932
dbainbri4d3a0dc2020-12-02 00:33:42 +00001933 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD for mcast", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001934 "EntitytId": strconv.FormatInt(int64(mcastVtfdID), 16), "mcastVlanID": vlanID,
1935 "in state": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
1936 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
1937
1938 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
1939 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
1940 // new vlan associated with a different TP.
1941 vtfdFilterList[0] = uint16(vlanID)
1942
1943 meParams = me.ParamData{
1944 EntityID: mcastVtfdID,
1945 Attributes: me.AttributeValueMap{
1946 "VlanFilterList": vtfdFilterList,
1947 "ForwardOperation": uint8(0x10), //VID investigation
1948 "NumberOfEntries": oFsm.numVlanFilterEntries,
1949 },
1950 }
1951 meInstance = oFsm.pOmciCC.sendCreateVtfdVar(context.TODO(), ConstDefaultOmciTimeout, true,
1952 oFsm.pAdaptFsm.commChan, meParams)
1953 oFsm.pLastTxMeInstance = meInstance
dbainbri4d3a0dc2020-12-02 00:33:42 +00001954 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001955 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001956 logger.Errorw(ctx, "CreateMcastVlanFilterData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001957 log.Fields{"device-id": oFsm.deviceID, "mcastVtfdID": mcastVtfdID})
mpagenko9a304ea2020-12-16 15:54:01 +00001958 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001959 return fmt.Errorf("createMcastVlanFilterData responseError %s, error %s", oFsm.deviceID, err)
1960 }
1961
1962 return nil
1963}
1964
dbainbri4d3a0dc2020-12-02 00:33:42 +00001965func (oFsm *UniVlanConfigFsm) performCreatingMulticastSubscriberConfigInfo(ctx context.Context) error {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001966 instID, err := oFsm.pDeviceHandler.getUniPortMEEntityID(oFsm.pOnuUniPort.portNo)
1967 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001968 logger.Errorw(ctx, "error fetching uni port me instance",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001969 log.Fields{"device-id": oFsm.deviceID, "portNo": oFsm.pOnuUniPort.portNo})
1970 return err
1971 }
1972 meParams := me.ParamData{
1973 EntityID: instID,
1974 Attributes: me.AttributeValueMap{
1975 "MeType": 0,
1976 //Direct reference to the Operation profile
1977 //TODO ANI side used on UNI side, not the clearest option.
1978 "MulticastOperationsProfilePointer": macBridgePortAniEID + uint16(oFsm.pOnuUniPort.macBpNo),
1979 },
1980 }
1981 meInstance := oFsm.pOmciCC.sendCreateMulticastSubConfigInfoVar(context.TODO(), ConstDefaultOmciTimeout, true,
1982 oFsm.pAdaptFsm.commChan, meParams)
1983 //accept also nil as (error) return value for writing to LastTx
1984 // - this avoids misinterpretation of new received OMCI messages
1985 oFsm.pLastTxMeInstance = meInstance
1986 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001987 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001988 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001989 logger.Errorw(ctx, "CreateMulticastSubConfigInfo create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001990 log.Fields{"device-id": oFsm.deviceID, "MulticastSubConfigInfo": instID})
1991 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s", oFsm.deviceID)
1992 }
1993 return nil
1994}
1995
dbainbri4d3a0dc2020-12-02 00:33:42 +00001996func (oFsm *UniVlanConfigFsm) performCreatingMulticastOperationProfile(ctx context.Context) error {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001997 instID := macBridgePortAniEID + uint16(oFsm.pOnuUniPort.macBpNo)
1998 meParams := me.ParamData{
1999 EntityID: instID,
2000 Attributes: me.AttributeValueMap{
2001 "IgmpVersion": 2,
2002 "IgmpFunction": 0,
2003 //0 means false
2004 "ImmediateLeave": 0,
2005 "Robustness": 2,
2006 "QuerierIp": 0,
2007 "QueryInterval": 125,
2008 "QuerierMaxResponseTime": 100,
2009 "LastMemberResponseTime": 10,
2010 //0 means false
2011 "UnauthorizedJoinBehaviour": 0,
2012 },
2013 }
2014 meInstance := oFsm.pOmciCC.sendCreateMulticastOperationProfileVar(context.TODO(), ConstDefaultOmciTimeout, true,
2015 oFsm.pAdaptFsm.commChan, meParams)
2016 //accept also nil as (error) return value for writing to LastTx
2017 // - this avoids misinterpretation of new received OMCI messages
2018 oFsm.pLastTxMeInstance = meInstance
2019 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002020 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002021 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002022 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002023 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
2024 return fmt.Errorf("createMulticastOperationProfile responseError %s", oFsm.deviceID)
2025 }
2026 return nil
2027}
2028
dbainbri4d3a0dc2020-12-02 00:33:42 +00002029func (oFsm *UniVlanConfigFsm) performSettingMulticastOperationProfile(ctx context.Context, multicastGemPortID uint16, vlanID uint32) error {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002030 instID := macBridgePortAniEID + uint16(oFsm.pOnuUniPort.macBpNo)
2031 //TODO check that this is correct
2032 // Table control
2033 //setCtrl = 1
2034 //rowPartId = 0
2035 //test = 0
2036 //rowKey = 0
2037 tableCtrlStr := "0100000000000000"
2038 tableCtrl := AsByteSlice(tableCtrlStr)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002039 dynamicAccessCL := make([]uint8, 24)
2040 copy(dynamicAccessCL, tableCtrl)
2041 //Multicast GemPortId
2042 binary.BigEndian.PutUint16(dynamicAccessCL[2:], multicastGemPortID)
2043 // python version waits for installation of flows, see line 723 onward of
2044 // brcm_openomci_onu_handler.py
2045 binary.BigEndian.PutUint16(dynamicAccessCL[4:], uint16(vlanID))
2046 //Source IP all to 0
2047 binary.BigEndian.PutUint32(dynamicAccessCL[6:], IPToInt32(net.IPv4(0, 0, 0, 0)))
2048 //TODO start and end are hardcoded, get from TP
2049 // Destination IP address start of range
2050 binary.BigEndian.PutUint32(dynamicAccessCL[10:], IPToInt32(net.IPv4(225, 0, 0, 0)))
2051 // Destination IP address end of range
2052 binary.BigEndian.PutUint32(dynamicAccessCL[14:], IPToInt32(net.IPv4(239, 255, 255, 255)))
2053 //imputed group bandwidth
2054 binary.BigEndian.PutUint16(dynamicAccessCL[18:], 0)
2055
2056 meParams := me.ParamData{
2057 EntityID: instID,
2058 Attributes: me.AttributeValueMap{
2059 "DynamicAccessControlListTable": dynamicAccessCL,
2060 },
2061 }
2062 meInstance := oFsm.pOmciCC.sendSetMulticastOperationProfileVar(context.TODO(), ConstDefaultOmciTimeout, true,
2063 oFsm.pAdaptFsm.commChan, meParams)
2064 //accept also nil as (error) return value for writing to LastTx
2065 // - this avoids misinterpretation of new received OMCI messages
2066 oFsm.pLastTxMeInstance = meInstance
2067 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002068 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002069 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002070 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002071 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
2072 return fmt.Errorf("createMulticastOperationProfile responseError %s", oFsm.deviceID)
2073 }
2074 return nil
2075}
Girish Gowdra26a40922021-01-29 17:14:34 -08002076
2077// IsFlowRemovePending returns true if there are pending flows to remove, else false.
2078func (oFsm *UniVlanConfigFsm) IsFlowRemovePending() bool {
2079 oFsm.mutexFlowParams.RLock()
2080 defer oFsm.mutexFlowParams.RUnlock()
2081 return len(oFsm.uniRemoveFlowsSlice) > 0
2082}