blob: 50ab5b1cf05e18aa4fc328cf35017605b52af956 [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"
87 vlanEvIncrFlowConfig = "vlanEvIncrFlowConfig"
mpagenkofc4f56e2020-11-04 17:17:49 +000088 vlanEvRenew = "vlanEvRenew"
mpagenko01e726e2020-10-23 09:45:29 +000089 vlanEvRemFlowConfig = "vlanEvRemFlowConfig"
90 vlanEvRemFlowDone = "vlanEvRemFlowDone"
91 vlanEvFlowDataRemoved = "vlanEvFlowDataRemoved"
Holger Hildebrandt394c5522020-09-11 11:23:01 +000092 //vlanEvTimeoutSimple = "vlanEvTimeoutSimple"
93 //vlanEvTimeoutMids = "vlanEvTimeoutMids"
Himani Chawla4d908332020-08-31 12:30:20 +053094 vlanEvReset = "vlanEvReset"
95 vlanEvRestart = "vlanEvRestart"
mpagenkodff5dda2020-08-28 11:52:01 +000096)
mpagenko01e726e2020-10-23 09:45:29 +000097
mpagenkodff5dda2020-08-28 11:52:01 +000098const (
99 // states of config PON ANI port FSM
100 vlanStDisabled = "vlanStDisabled"
101 vlanStStarting = "vlanStStarting"
102 vlanStWaitingTechProf = "vlanStWaitingTechProf"
103 vlanStConfigVtfd = "vlanStConfigVtfd"
104 vlanStConfigEvtocd = "vlanStConfigEvtocd"
105 vlanStConfigDone = "vlanStConfigDone"
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000106 vlanStConfigIncrFlow = "vlanStConfigIncrFlow"
mpagenko01e726e2020-10-23 09:45:29 +0000107 vlanStRemoveFlow = "vlanStRemoveFlow"
mpagenkodff5dda2020-08-28 11:52:01 +0000108 vlanStCleanupDone = "vlanStCleanupDone"
109 vlanStResetting = "vlanStResetting"
110)
111
mpagenko01e726e2020-10-23 09:45:29 +0000112type uniVlanRuleParams struct {
113 TpID uint16 `json:"tp_id"`
114 MatchVid uint32 `json:"match_vid"` //use uint32 types for allowing immediate bitshifting
115 MatchPcp uint32 `json:"match_pcp"`
116 TagsToRemove uint32 `json:"tags_to_remove"`
117 SetVid uint32 `json:"set_vid"`
118 SetPcp uint32 `json:"set_pcp"`
119}
120
121type uniVlanFlowParams struct {
122 CookieSlice []uint64 `json:"cookie_slice"`
123 VlanRuleParams uniVlanRuleParams `json:"vlan_rule_params"`
124}
125
126type uniRemoveVlanFlowParams struct {
127 cookie uint64 //just the last cookie valid for removal
128 vlanRuleParams uniVlanRuleParams
129}
130
mpagenkodff5dda2020-08-28 11:52:01 +0000131//UniVlanConfigFsm defines the structure for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
132type UniVlanConfigFsm struct {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530133 pDeviceHandler *deviceHandler
mpagenko01e726e2020-10-23 09:45:29 +0000134 deviceID string
Himani Chawla6d2ae152020-09-02 13:11:20 +0530135 pOmciCC *omciCC
136 pOnuUniPort *onuUniPort
137 pUniTechProf *onuUniTechProf
138 pOnuDB *onuDeviceDB
mpagenkodff5dda2020-08-28 11:52:01 +0000139 requestEvent OnuDeviceEvent
140 omciMIdsResponseReceived chan bool //seperate channel needed for checking multiInstance OMCI message responses
141 pAdaptFsm *AdapterFsm
142 acceptIncrementalEvtoOption bool
mpagenko2418ab02020-11-12 12:58:06 +0000143 clearPersistency bool
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000144 mutexFlowParams sync.Mutex
mpagenko01e726e2020-10-23 09:45:29 +0000145 uniVlanFlowParamsSlice []uniVlanFlowParams
146 uniRemoveFlowsSlice []uniRemoveVlanFlowParams
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000147 numUniFlows uint8 // expected number of flows should be less than 12
148 configuredUniFlow uint8
mpagenko01e726e2020-10-23 09:45:29 +0000149 numRemoveFlows uint8
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000150 numVlanFilterEntries uint8
mpagenko01e726e2020-10-23 09:45:29 +0000151 vlanFilterList [cVtfdTableSize]uint16
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000152 evtocdID uint16
mpagenko01e726e2020-10-23 09:45:29 +0000153 pLastTxMeInstance *me.ManagedEntity
mpagenkofc4f56e2020-11-04 17:17:49 +0000154 requestEventOffset uint8
mpagenkodff5dda2020-08-28 11:52:01 +0000155}
156
mpagenko01e726e2020-10-23 09:45:29 +0000157//NewUniVlanConfigFsm is the 'constructor' for the state machine to config the PON ANI ports
158// of ONU UNI ports via OMCI
dbainbri4d3a0dc2020-12-02 00:33:42 +0000159func NewUniVlanConfigFsm(ctx context.Context, apDeviceHandler *deviceHandler, apDevOmciCC *omciCC, apUniPort *onuUniPort,
mpagenko01e726e2020-10-23 09:45:29 +0000160 apUniTechProf *onuUniTechProf, apOnuDB *onuDeviceDB, aTechProfileID uint16,
161 aRequestEvent OnuDeviceEvent, aName string, aCommChannel chan Message, aAcceptIncrementalEvto bool,
162 aCookieSlice []uint64, aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) *UniVlanConfigFsm {
mpagenkodff5dda2020-08-28 11:52:01 +0000163 instFsm := &UniVlanConfigFsm{
164 pDeviceHandler: apDeviceHandler,
mpagenko01e726e2020-10-23 09:45:29 +0000165 deviceID: apDeviceHandler.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +0000166 pOmciCC: apDevOmciCC,
167 pOnuUniPort: apUniPort,
168 pUniTechProf: apUniTechProf,
169 pOnuDB: apOnuDB,
mpagenkodff5dda2020-08-28 11:52:01 +0000170 requestEvent: aRequestEvent,
171 acceptIncrementalEvtoOption: aAcceptIncrementalEvto,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000172 numUniFlows: 0,
173 configuredUniFlow: 0,
mpagenko01e726e2020-10-23 09:45:29 +0000174 numRemoveFlows: 0,
mpagenko2418ab02020-11-12 12:58:06 +0000175 clearPersistency: true,
mpagenkodff5dda2020-08-28 11:52:01 +0000176 }
177
mpagenko01e726e2020-10-23 09:45:29 +0000178 instFsm.pAdaptFsm = NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
mpagenkodff5dda2020-08-28 11:52:01 +0000179 if instFsm.pAdaptFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000180 logger.Errorw(ctx, "UniVlanConfigFsm's AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000181 "device-id": instFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000182 return nil
183 }
mpagenkodff5dda2020-08-28 11:52:01 +0000184 instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
185 vlanStDisabled,
186 fsm.Events{
187 {Name: vlanEvStart, Src: []string{vlanStDisabled}, Dst: vlanStStarting},
188 {Name: vlanEvWaitTechProf, Src: []string{vlanStStarting}, Dst: vlanStWaitingTechProf},
189 {Name: vlanEvContinueConfig, Src: []string{vlanStWaitingTechProf}, Dst: vlanStConfigVtfd},
190 {Name: vlanEvStartConfig, Src: []string{vlanStStarting}, Dst: vlanStConfigVtfd},
191 {Name: vlanEvRxConfigVtfd, Src: []string{vlanStConfigVtfd}, Dst: vlanStConfigEvtocd},
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000192 {Name: vlanEvRxConfigEvtocd, Src: []string{vlanStConfigEvtocd, vlanStConfigIncrFlow},
193 Dst: vlanStConfigDone},
194 {Name: vlanEvIncrFlowConfig, Src: []string{vlanStConfigDone}, Dst: vlanStConfigIncrFlow},
mpagenkofc4f56e2020-11-04 17:17:49 +0000195 {Name: vlanEvRenew, Src: []string{vlanStConfigIncrFlow}, Dst: vlanStStarting},
mpagenko01e726e2020-10-23 09:45:29 +0000196 {Name: vlanEvRemFlowConfig, Src: []string{vlanStConfigDone}, Dst: vlanStRemoveFlow},
197 {Name: vlanEvRemFlowDone, Src: []string{vlanStRemoveFlow}, Dst: vlanStCleanupDone},
198 {Name: vlanEvFlowDataRemoved, Src: []string{vlanStCleanupDone}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000199 /*
200 {Name: vlanEvTimeoutSimple, Src: []string{
201 vlanStCreatingDot1PMapper, vlanStCreatingMBPCD, vlanStSettingTconts, vlanStSettingDot1PMapper}, Dst: vlanStStarting},
202 {Name: vlanEvTimeoutMids, Src: []string{
203 vlanStCreatingGemNCTPs, vlanStCreatingGemIWs, vlanStSettingPQs}, Dst: vlanStStarting},
204 */
205 // exceptional treatment for all states except vlanStResetting
206 {Name: vlanEvReset, Src: []string{vlanStStarting, vlanStWaitingTechProf,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000207 vlanStConfigVtfd, vlanStConfigEvtocd, vlanStConfigDone, vlanStConfigIncrFlow,
mpagenko01e726e2020-10-23 09:45:29 +0000208 vlanStRemoveFlow, vlanStCleanupDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000209 Dst: vlanStResetting},
210 // the only way to get to resource-cleared disabled state again is via "resseting"
211 {Name: vlanEvRestart, Src: []string{vlanStResetting}, Dst: vlanStDisabled},
212 },
mpagenkodff5dda2020-08-28 11:52:01 +0000213 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000214 "enter_state": func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(ctx, e) },
215 "enter_" + vlanStStarting: func(e *fsm.Event) { instFsm.enterConfigStarting(ctx, e) },
216 "enter_" + vlanStConfigVtfd: func(e *fsm.Event) { instFsm.enterConfigVtfd(ctx, e) },
217 "enter_" + vlanStConfigEvtocd: func(e *fsm.Event) { instFsm.enterConfigEvtocd(ctx, e) },
218 "enter_" + vlanStConfigDone: func(e *fsm.Event) { instFsm.enterVlanConfigDone(ctx, e) },
219 "enter_" + vlanStConfigIncrFlow: func(e *fsm.Event) { instFsm.enterConfigIncrFlow(ctx, e) },
220 "enter_" + vlanStRemoveFlow: func(e *fsm.Event) { instFsm.enterRemoveFlow(ctx, e) },
221 "enter_" + vlanStCleanupDone: func(e *fsm.Event) { instFsm.enterVlanCleanupDone(ctx, e) },
222 "enter_" + vlanStResetting: func(e *fsm.Event) { instFsm.enterResetting(ctx, e) },
223 "enter_" + vlanStDisabled: func(e *fsm.Event) { instFsm.enterDisabled(ctx, e) },
mpagenkodff5dda2020-08-28 11:52:01 +0000224 },
225 )
226 if instFsm.pAdaptFsm.pFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000227 logger.Errorw(ctx, "UniVlanConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000228 "device-id": instFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000229 return nil
230 }
231
dbainbri4d3a0dc2020-12-02 00:33:42 +0000232 _ = instFsm.initUniFlowParams(ctx, aTechProfileID, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000233
dbainbri4d3a0dc2020-12-02 00:33:42 +0000234 logger.Debugw(ctx, "UniVlanConfigFsm created", log.Fields{"device-id": instFsm.deviceID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000235 "accIncrEvto": instFsm.acceptIncrementalEvtoOption})
mpagenkodff5dda2020-08-28 11:52:01 +0000236 return instFsm
237}
238
mpagenko01e726e2020-10-23 09:45:29 +0000239//initUniFlowParams is a simplified form of SetUniFlowParams() used for first flow parameters configuration
dbainbri4d3a0dc2020-12-02 00:33:42 +0000240func (oFsm *UniVlanConfigFsm) initUniFlowParams(ctx context.Context, aTpID uint16, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +0000241 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) error {
242 loRuleParams := uniVlanRuleParams{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000243 TpID: aTpID,
244 MatchVid: uint32(aMatchVlan),
245 SetVid: uint32(aSetVlan),
246 SetPcp: uint32(aSetPcp),
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000247 }
248 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
mpagenko01e726e2020-10-23 09:45:29 +0000249 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
250 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000251
mpagenko01e726e2020-10-23 09:45:29 +0000252 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000253 //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 +0000254 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000255 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
256 } else {
257 if !oFsm.acceptIncrementalEvtoOption {
258 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000259 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000260 }
261 }
262
mpagenko01e726e2020-10-23 09:45:29 +0000263 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000264 // no prio/vid filtering requested
mpagenko01e726e2020-10-23 09:45:29 +0000265 loRuleParams.TagsToRemove = 0 //no tag pop action
266 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
267 if loRuleParams.SetPcp == cCopyPrioFromInner {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000268 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
269 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
270 // might collide with NoMatchVid/CopyPrio(/setVid) setting
271 // this was some precondition setting taken over from py adapter ..
mpagenko01e726e2020-10-23 09:45:29 +0000272 loRuleParams.SetPcp = 0
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000273 }
274 }
mpagenko01e726e2020-10-23 09:45:29 +0000275
276 loFlowParams := uniVlanFlowParams{VlanRuleParams: loRuleParams}
277 loFlowParams.CookieSlice = make([]uint64, 0)
278 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
279
280 //no mutex protection is required for initial access and adding the first flow is always possible
281 oFsm.uniVlanFlowParamsSlice = make([]uniVlanFlowParams, 0)
282 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000283 logger.Debugw(ctx, "first UniVlanConfigFsm flow added", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000284 "Cookies": oFsm.uniVlanFlowParamsSlice[0].CookieSlice,
285 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
286 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
287 "SetPcp": loRuleParams.SetPcp,
288 "device-id": oFsm.deviceID})
289 oFsm.numUniFlows = 1
290 oFsm.uniRemoveFlowsSlice = make([]uniRemoveVlanFlowParams, 0) //initially nothing to remove
291
292 //permanently store flow config for reconcile case
dbainbri4d3a0dc2020-12-02 00:33:42 +0000293 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
mpagenko01e726e2020-10-23 09:45:29 +0000294 &oFsm.uniVlanFlowParamsSlice); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000295 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000296 return err
297 }
298
299 return nil
300}
301
mpagenko2418ab02020-11-12 12:58:06 +0000302//RequestClearPersistency sets the internal flag to not clear persistency data (false=NoClear)
303func (oFsm *UniVlanConfigFsm) RequestClearPersistency(aClear bool) {
304 //mutex protection is required for possible concurrent access to FSM members
305 oFsm.mutexFlowParams.Lock()
306 defer oFsm.mutexFlowParams.Unlock()
307 oFsm.clearPersistency = aClear
308}
309
mpagenko01e726e2020-10-23 09:45:29 +0000310//SetUniFlowParams verifies on existence of flow parameters to be configured,
311// optionally udates the cookie list or appends a new flow if there is space
312// if possible the FSM is trigggerd to start with the processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000313func (oFsm *UniVlanConfigFsm) SetUniFlowParams(ctx context.Context, aTpID uint16, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +0000314 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) error {
315 loRuleParams := uniVlanRuleParams{
316 TpID: aTpID,
317 MatchVid: uint32(aMatchVlan),
318 SetVid: uint32(aSetVlan),
319 SetPcp: uint32(aSetPcp),
320 }
321 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
322 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
323 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
324
325 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
326 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
327 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
328 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
329 } else {
330 if !oFsm.acceptIncrementalEvtoOption {
331 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
332 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
333 }
334 }
335
336 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
337 // no prio/vid filtering requested
338 loRuleParams.TagsToRemove = 0 //no tag pop action
339 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
340 if loRuleParams.SetPcp == cCopyPrioFromInner {
341 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
342 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
343 // might collide with NoMatchVid/CopyPrio(/setVid) setting
344 // this was some precondition setting taken over from py adapter ..
345 loRuleParams.SetPcp = 0
346 }
347 }
348
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000349 flowEntryMatch := false
mpagenko01e726e2020-10-23 09:45:29 +0000350 flowCookieModify := false
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000351 //mutex protection is required for possible concurrent access to FSM members
352 oFsm.mutexFlowParams.Lock()
353 defer oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000354 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
355 //TODO: Verify if using e.g. hashes for the structures here for comparison may generate
356 // countable run time optimization (perhaps with including the hash in kvStore storage?)
357 if storedUniFlowParams.VlanRuleParams == loRuleParams {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000358 flowEntryMatch = true
dbainbri4d3a0dc2020-12-02 00:33:42 +0000359 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - rule already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000360 "device-id": oFsm.deviceID})
361 var cookieMatch bool
362 for _, newCookie := range aCookieSlice { // for all cookies available in the arguments
363 cookieMatch = false
364 for _, cookie := range storedUniFlowParams.CookieSlice {
365 if cookie == newCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000366 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - and cookie already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000367 "device-id": oFsm.deviceID, "cookie": cookie})
368 cookieMatch = true
369 break //found new cookie - no further search for this requested cookie
370 }
371 }
372 if !cookieMatch {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000373 logger.Debugw(ctx, "UniVlanConfigFsm flow setting -adding new cookie", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000374 "device-id": oFsm.deviceID, "cookie": newCookie})
375 //as range works with copies of the slice we have to write to the original slice!!
376 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
377 newCookie)
378 flowCookieModify = true
379 }
380 } //for all new cookies
381 break // found rule - no further rule search
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000382 }
383 }
mpagenko01e726e2020-10-23 09:45:29 +0000384 if !flowEntryMatch { //it is a new rule
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000385 if oFsm.numUniFlows < cMaxAllowedFlows {
mpagenko01e726e2020-10-23 09:45:29 +0000386 loFlowParams := uniVlanFlowParams{VlanRuleParams: loRuleParams}
387 loFlowParams.CookieSlice = make([]uint64, 0)
388 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
389 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000390 logger.Debugw(ctx, "UniVlanConfigFsm flow add", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000391 "Cookies": oFsm.uniVlanFlowParamsSlice[oFsm.numUniFlows].CookieSlice,
392 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
393 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
Girish Gowdra041dcb32020-11-16 16:54:30 -0800394 "SetPcp": loRuleParams.SetPcp, "numberofFlows": oFsm.numUniFlows + 1,
mpagenko01e726e2020-10-23 09:45:29 +0000395 "device-id": oFsm.deviceID})
396
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000397 oFsm.numUniFlows++
mpagenko01e726e2020-10-23 09:45:29 +0000398 // note: theoretical it would be possible to clear the same rule from the remove slice
399 // (for entries that have not yet been started with removal)
400 // but that is getting quite complicated - maybe a future optimization in case it should prove reasonable
401 // 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 +0000402
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000403 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
404 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
405 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
406 // calling some FSM event must be decoupled
407 go func(a_pBaseFsm *fsm.FSM) {
408 _ = a_pBaseFsm.Event(vlanEvIncrFlowConfig)
409 }(pConfigVlanStateBaseFsm)
mpagenko01e726e2020-10-23 09:45:29 +0000410 } // if not in the appropriate state a new entry will be automatically considered later
411 // when the configDone state is reached
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000412 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000413 logger.Errorw(ctx, "UniVlanConfigFsm flow limit exceeded", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000414 "device-id": oFsm.deviceID, "flow-number": oFsm.numUniFlows})
415 return fmt.Errorf(" UniVlanConfigFsm flow limit exceeded %s", oFsm.deviceID)
416 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000417 } else {
418 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
419 if oFsm.numUniFlows == oFsm.configuredUniFlow {
420 //all requested rules really have been configured
421 // state transition notification is checked in deviceHandler
422 if oFsm.pDeviceHandler != nil {
423 //also the related TechProfile was already configured
dbainbri4d3a0dc2020-12-02 00:33:42 +0000424 logger.Debugw(ctx, "UniVlanConfigFsm rule already set - send immediate add-success event for reason update", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +0000425 "device-id": oFsm.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000426 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, oFsm.requestEvent)
mpagenkofc4f56e2020-11-04 17:17:49 +0000427 }
428 } else {
429 // avoid device reason update as the rule config connected to this flow may still be in progress
430 // and the device reason should only be updated on success of rule config
dbainbri4d3a0dc2020-12-02 00:33:42 +0000431 logger.Debugw(ctx, "UniVlanConfigFsm rule already set but configuration ongoing, suppress early add-success event for reason update",
mpagenkofc4f56e2020-11-04 17:17:49 +0000432 log.Fields{"device-id": oFsm.deviceID,
433 "NumberofRules": oFsm.numUniFlows, "Configured rules": oFsm.configuredUniFlow})
434 }
435 }
mpagenko01e726e2020-10-23 09:45:29 +0000436
437 if !flowEntryMatch || flowCookieModify { // some change was done to the flow entries
438 //permanently store flow config for reconcile case
dbainbri4d3a0dc2020-12-02 00:33:42 +0000439 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID, &oFsm.uniVlanFlowParamsSlice); err != nil {
440 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000441 return err
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000442 }
443 }
444 return nil
445}
446
mpagenko01e726e2020-10-23 09:45:29 +0000447//RemoveUniFlowParams verifies on existence of flow cookie,
448// if found removes cookie from flow cookie list and if this is empty
449// initiates removal of the flow related configuration from the ONU (via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000450func (oFsm *UniVlanConfigFsm) RemoveUniFlowParams(ctx context.Context, aCookie uint64) error {
mpagenko01e726e2020-10-23 09:45:29 +0000451 flowCookieMatch := false
452 //mutex protection is required for possible concurrent access to FSM members
453 oFsm.mutexFlowParams.Lock()
454 defer oFsm.mutexFlowParams.Unlock()
455 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
456 for i, cookie := range storedUniFlowParams.CookieSlice {
457 if cookie == aCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000458 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - cookie found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000459 "device-id": oFsm.deviceID, "cookie": cookie})
460 flowCookieMatch = true
461
462 //remove the cookie from the cookie slice and verify it is getting empty
463 if len(storedUniFlowParams.CookieSlice) == 1 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000464 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - full flow removal", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000465 "device-id": oFsm.deviceID})
466 oFsm.numUniFlows--
467
468 //create a new element for the removeVlanFlow slice
469 loRemoveParams := uniRemoveVlanFlowParams{
470 vlanRuleParams: storedUniFlowParams.VlanRuleParams,
471 cookie: storedUniFlowParams.CookieSlice[0],
472 }
473 oFsm.uniRemoveFlowsSlice = append(oFsm.uniRemoveFlowsSlice, loRemoveParams)
474
475 //and remove the actual element from the addVlanFlow slice
476 // oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = nil //automatically done by garbage collector
477 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
478 oFsm.numUniFlows = 0 //no more flows
479 oFsm.configuredUniFlow = 0 //no more flows configured
480 oFsm.uniVlanFlowParamsSlice = nil //reset the slice
mpagenko2418ab02020-11-12 12:58:06 +0000481 //at this point it is evident that no flow anymore refers to a still possibly active Techprofile
482 //request that this profile gets deleted before a new flow add is allowed
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300483 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, uint8(loRemoveParams.vlanRuleParams.TpID), true)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000484 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - no more flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000485 "device-id": oFsm.deviceID})
486 } else {
487 oFsm.numUniFlows--
488 if oFsm.configuredUniFlow > 0 {
489 oFsm.configuredUniFlow--
490 //TODO!! might be needed to consider still outstanding configure requests ..
491 // so a flow at removal might still not be configured !?!
492 }
mpagenko2418ab02020-11-12 12:58:06 +0000493 usedTpID := storedUniFlowParams.VlanRuleParams.TpID
mpagenko01e726e2020-10-23 09:45:29 +0000494 //cut off the requested flow by slicing out this element
495 oFsm.uniVlanFlowParamsSlice = append(
496 oFsm.uniVlanFlowParamsSlice[:flow], oFsm.uniVlanFlowParamsSlice[flow+1:]...)
mpagenko2418ab02020-11-12 12:58:06 +0000497 //here we have to check, if there are still other flows referencing to the actual ProfileId
498 // before we can request that this profile gets deleted before a new flow add is allowed
499 tpIDInOtherFlows := false
500 for _, tpUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
501 if tpUniFlowParams.VlanRuleParams.TpID == usedTpID {
502 tpIDInOtherFlows = true
503 break // search loop can be left
504 }
505 }
506 if tpIDInOtherFlows {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000507 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is still used in other flows", log.Fields{
mpagenko2418ab02020-11-12 12:58:06 +0000508 "device-id": oFsm.deviceID, "tp-id": usedTpID})
509 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000510 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is not used anymore", log.Fields{
mpagenko2418ab02020-11-12 12:58:06 +0000511 "device-id": oFsm.deviceID, "tp-id": usedTpID})
512 //request that this profile gets deleted before a new flow add is allowed
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300513 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, uint8(usedTpID), true)
mpagenko2418ab02020-11-12 12:58:06 +0000514 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000515 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow removed from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000516 "device-id": oFsm.deviceID})
517 }
518 //trigger the FSM to remove the relevant rule
519 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
520 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
521 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
522 // calling some FSM event must be decoupled
523 go func(a_pBaseFsm *fsm.FSM) {
524 _ = a_pBaseFsm.Event(vlanEvRemFlowConfig)
525 }(pConfigVlanStateBaseFsm)
526 } // if not in the appropriate state a new entry will be automatically considered later
527 // when the configDone state is reached
528 } else {
mpagenko01e726e2020-10-23 09:45:29 +0000529 //cut off the requested cookie by slicing out this element
530 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(
531 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[:i],
532 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[i+1:]...)
mpagenkofc4f56e2020-11-04 17:17:49 +0000533 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
534 // state transition notification is checked in deviceHandler
535 if oFsm.pDeviceHandler != nil {
536 //making use of the add->remove successor enum assumption/definition
dbainbri4d3a0dc2020-12-02 00:33:42 +0000537 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(uint8(oFsm.requestEvent)+1))
mpagenkofc4f56e2020-11-04 17:17:49 +0000538 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000539 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - rule persists with still valid cookies", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000540 "device-id": oFsm.deviceID, "cookies": oFsm.uniVlanFlowParamsSlice[flow].CookieSlice})
541 }
542
543 //permanently store the modified flow config for reconcile case
mpagenkofc4f56e2020-11-04 17:17:49 +0000544 if oFsm.pDeviceHandler != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000545 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID, &oFsm.uniVlanFlowParamsSlice); err != nil {
546 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +0000547 return err
548 }
mpagenko01e726e2020-10-23 09:45:29 +0000549 }
550
551 break //found the cookie - no further search for this requested cookie
552 }
553 }
554 if flowCookieMatch { //cookie already found: no need for further search in other flows
555 break
556 }
557 } //search all flows
558 if !flowCookieMatch { //some cookie remove-request for a cookie that does not exist in the FSM data
dbainbri4d3a0dc2020-12-02 00:33:42 +0000559 logger.Warnw(ctx, "UniVlanConfigFsm flow removal - remove-cookie not found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000560 "device-id": oFsm.deviceID, "remove-cookie": aCookie})
561 // but accept the request with success as no such cookie (flow) does exist
mpagenkofc4f56e2020-11-04 17:17:49 +0000562 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
563 // state transition notification is checked in deviceHandler
564 if oFsm.pDeviceHandler != nil {
565 //making use of the add->remove successor enum assumption/definition
dbainbri4d3a0dc2020-12-02 00:33:42 +0000566 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(uint8(oFsm.requestEvent)+1))
mpagenkofc4f56e2020-11-04 17:17:49 +0000567 }
mpagenko01e726e2020-10-23 09:45:29 +0000568 return nil
569 } //unknown cookie
570
571 return nil
572}
573
dbainbri4d3a0dc2020-12-02 00:33:42 +0000574func (oFsm *UniVlanConfigFsm) enterConfigStarting(ctx context.Context, e *fsm.Event) {
575 logger.Debugw(ctx, "UniVlanConfigFsm start", log.Fields{"in state": e.FSM.Current(),
mpagenko01e726e2020-10-23 09:45:29 +0000576 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000577
578 // this FSM is not intended for re-start, needs always new creation for a new run
mpagenko01e726e2020-10-23 09:45:29 +0000579 // (self-destroying - compare enterDisabled())
mpagenkodff5dda2020-08-28 11:52:01 +0000580 oFsm.omciMIdsResponseReceived = make(chan bool)
581 // start go routine for processing of LockState messages
dbainbri4d3a0dc2020-12-02 00:33:42 +0000582 go oFsm.processOmciVlanMessages(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +0000583 //let the state machine run forward from here directly
584 pConfigVlanStateAFsm := oFsm.pAdaptFsm
585 if pConfigVlanStateAFsm != nil {
586 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
587 go func(a_pAFsm *AdapterFsm) {
588 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300589 tpID := oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams.TpID
mpagenkodff5dda2020-08-28 11:52:01 +0000590 //cmp also usage in EVTOCDE create in omci_cc
591 oFsm.evtocdID = macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo)
592
dbainbri4d3a0dc2020-12-02 00:33:42 +0000593 if oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
mpagenkodff5dda2020-08-28 11:52:01 +0000594 // let the vlan processing begin
Himani Chawla4d908332020-08-31 12:30:20 +0530595 _ = a_pAFsm.pFsm.Event(vlanEvStartConfig)
mpagenkodff5dda2020-08-28 11:52:01 +0000596 } else {
597 // set to waiting for Techprofile
Himani Chawla4d908332020-08-31 12:30:20 +0530598 _ = a_pAFsm.pFsm.Event(vlanEvWaitTechProf)
mpagenkodff5dda2020-08-28 11:52:01 +0000599 }
600 }
601 }(pConfigVlanStateAFsm)
602 }
603}
604
dbainbri4d3a0dc2020-12-02 00:33:42 +0000605func (oFsm *UniVlanConfigFsm) enterConfigVtfd(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000606 //mutex protection is required for possible concurrent access to FSM members
607 oFsm.mutexFlowParams.Lock()
mpagenko8b07c1b2020-11-26 10:36:31 +0000608 if len(oFsm.uniVlanFlowParamsSlice) == 0 {
609 //possibly the entry is not valid anymore based on intermediate delete requests
610 //just a basic protection ...
611 oFsm.mutexFlowParams.Unlock()
612 pConfigVlanStateAFsm := oFsm.pAdaptFsm
613 go func(a_pAFsm *AdapterFsm) {
614 _ = a_pAFsm.pFsm.Event(vlanEvReset)
615 }(pConfigVlanStateAFsm)
616 return
617 }
mpagenko01e726e2020-10-23 09:45:29 +0000618 if oFsm.uniVlanFlowParamsSlice[0].VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +0000619 // meaning transparent setup - no specific VTFD setting required
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000620 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000621 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000622 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000623 // let the FSM proceed ... (from within this state all internal pointers may be expected to be correct)
624 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
625 pConfigVlanStateAFsm := oFsm.pAdaptFsm
626 go func(a_pAFsm *AdapterFsm) {
Himani Chawla4d908332020-08-31 12:30:20 +0530627 _ = a_pAFsm.pFsm.Event(vlanEvRxConfigVtfd)
mpagenkodff5dda2020-08-28 11:52:01 +0000628 }(pConfigVlanStateAFsm)
629 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300630 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
631 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
632 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + oFsm.uniVlanFlowParamsSlice[0].VlanRuleParams.TpID
dbainbri4d3a0dc2020-12-02 00:33:42 +0000633 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300634 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000635 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
636 // setVid is assumed to be masked already by the caller to 12 bit
637 oFsm.vlanFilterList[0] = uint16(oFsm.uniVlanFlowParamsSlice[0].VlanRuleParams.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000638 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000639 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000640 vtfdFilterList[0] = oFsm.vlanFilterList[0]
641 oFsm.numVlanFilterEntries = 1
mpagenkodff5dda2020-08-28 11:52:01 +0000642 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300643 EntityID: vtfdID,
mpagenkodff5dda2020-08-28 11:52:01 +0000644 Attributes: me.AttributeValueMap{
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000645 "VlanFilterList": vtfdFilterList, //omci lib wants a slice for serialization
646 "ForwardOperation": uint8(0x10), //VID investigation
647 "NumberOfEntries": oFsm.numVlanFilterEntries,
mpagenkodff5dda2020-08-28 11:52:01 +0000648 },
649 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000650 logger.Debugw(ctx, "UniVlanConfigFsm sendcreate VTFD", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000651 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000652 meInstance := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +0000653 oFsm.pAdaptFsm.commChan, meParams)
654 //accept also nil as (error) return value for writing to LastTx
655 // - this avoids misinterpretation of new received OMCI messages
656 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
657 // send shall return (dual format) error code that can be used here for immediate error treatment
658 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +0000659 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +0000660 }
661}
662
dbainbri4d3a0dc2020-12-02 00:33:42 +0000663func (oFsm *UniVlanConfigFsm) enterConfigEvtocd(ctx context.Context, e *fsm.Event) {
664 logger.Debugw(ctx, "UniVlanConfigFsm - start config EVTOCD loop", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000665 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +0000666 oFsm.requestEventOffset = 0 //0 offset for last flow-add activity
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300667 go func() {
668 tpID := oFsm.uniVlanFlowParamsSlice[0].VlanRuleParams.TpID
669 vlanID := oFsm.uniVlanFlowParamsSlice[0].VlanRuleParams.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +0000670 errEvto := oFsm.performConfigEvtocdEntries(ctx, oFsm.configuredUniFlow)
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300671 //This is correct passing scenario
672 if errEvto == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000673 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
674 logger.Infow(ctx, "Setting multicast MEs, with first flow", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300675 "techProfile": tpID, "gemPort": gemPort, "vlanID": vlanID, "configuredUniFlow": oFsm.configuredUniFlow})
676 //can Use the first elements in the slice because it's the first flow.
dbainbri4d3a0dc2020-12-02 00:33:42 +0000677 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300678 vlanID)
679 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000680 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300681 log.Fields{"device-id": oFsm.deviceID})
682 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
683 }
684 }
685 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
686 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
687 }
688 }()
mpagenkodff5dda2020-08-28 11:52:01 +0000689}
690
dbainbri4d3a0dc2020-12-02 00:33:42 +0000691func (oFsm *UniVlanConfigFsm) enterVlanConfigDone(ctx context.Context, e *fsm.Event) {
692 logger.Debugw(ctx, "UniVlanConfigFsm - checking on more flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000693 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
694 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
695 if len(oFsm.uniRemoveFlowsSlice) > 0 {
696 //some further flows are to be removed, removal always starts with the first element
697 // calling some FSM event must be decoupled
698 go func(a_pBaseFsm *fsm.FSM) {
699 _ = a_pBaseFsm.Event(vlanEvRemFlowConfig)
700 }(pConfigVlanStateBaseFsm)
701 return
702 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000703 if oFsm.numUniFlows > oFsm.configuredUniFlow {
704 //some further flows are to be configured
705 // calling some FSM event must be decoupled
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000706 go func(a_pBaseFsm *fsm.FSM) {
707 _ = a_pBaseFsm.Event(vlanEvIncrFlowConfig)
708 }(pConfigVlanStateBaseFsm)
709 return
710 }
711
dbainbri4d3a0dc2020-12-02 00:33:42 +0000712 logger.Debugw(ctx, "UniVlanConfigFsm - VLAN config done: send dh event notification", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000713 "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000714 // it might appear that some flows are requested also after 'flowPushed' event has been generated ...
715 // state transition notification is checked in deviceHandler
mpagenkodff5dda2020-08-28 11:52:01 +0000716 if oFsm.pDeviceHandler != nil {
mpagenkofc4f56e2020-11-04 17:17:49 +0000717 //making use of the add->remove successor enum assumption/definition
dbainbri4d3a0dc2020-12-02 00:33:42 +0000718 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(uint8(oFsm.requestEvent)+oFsm.requestEventOffset))
mpagenkodff5dda2020-08-28 11:52:01 +0000719 }
720}
721
dbainbri4d3a0dc2020-12-02 00:33:42 +0000722func (oFsm *UniVlanConfigFsm) enterConfigIncrFlow(ctx context.Context, e *fsm.Event) {
723 logger.Debugw(ctx, "UniVlanConfigFsm - start config further incremental flow", log.Fields{
Girish Gowdra041dcb32020-11-16 16:54:30 -0800724 "in state": e.FSM.Current(), "recent flow-number": oFsm.configuredUniFlow,
mpagenko01e726e2020-10-23 09:45:29 +0000725 "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000726 oFsm.mutexFlowParams.Lock()
727
mpagenkofc4f56e2020-11-04 17:17:49 +0000728 if oFsm.configuredUniFlow == 0 {
729 oFsm.mutexFlowParams.Unlock()
730 // this is a restart with a complete new flow, we can re-use the initial flow config control
731 // including the check, if the related techProfile is (still) available (probably also removed in between)
732 // calling some FSM event must be decoupled
733 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
734 go func(a_pBaseFsm *fsm.FSM) {
735 _ = a_pBaseFsm.Event(vlanEvRenew)
736 }(pConfigVlanStateBaseFsm)
737 return
738 }
mpagenko8b07c1b2020-11-26 10:36:31 +0000739 if uint8(len(oFsm.uniVlanFlowParamsSlice)) < oFsm.configuredUniFlow {
740 //possibly the entry is not valid anymore based on intermediate delete requests
741 //just a basic protection ...
742 oFsm.mutexFlowParams.Unlock()
743 pConfigVlanStateAFsm := oFsm.pAdaptFsm
744 go func(a_pAFsm *AdapterFsm) {
745 _ = a_pAFsm.pFsm.Event(vlanEvReset)
746 }(pConfigVlanStateAFsm)
747 return
748 }
mpagenko01e726e2020-10-23 09:45:29 +0000749 if oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000750 // meaning transparent setup - no specific VTFD setting required
751 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000752 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000753 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000754 } else {
755 if oFsm.numVlanFilterEntries == 0 {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300756 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
757 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
758 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + oFsm.uniVlanFlowParamsSlice[0].VlanRuleParams.TpID
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000759 //no VTFD yet created
dbainbri4d3a0dc2020-12-02 00:33:42 +0000760 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300761 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000762 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300763 // FIXME: VOL-3673: using oFsm.uniVlanFlowParamsSlice[0] is incorrect here, as the relevant (first) VTFD may
764 // result from some incremented rule (not all rules enforce a VTFD configuration). But this is Ok for the
765 // current scenarios we support.
766 // 'SetVid' below is assumed to be masked already by the caller to 12 bit
767 oFsm.vlanFilterList[0] = uint16(oFsm.uniVlanFlowParamsSlice[0].VlanRuleParams.SetVid)
768
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000769 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000770 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000771 vtfdFilterList[0] = oFsm.vlanFilterList[0]
772 oFsm.numVlanFilterEntries = 1
773 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300774 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000775 Attributes: me.AttributeValueMap{
776 "VlanFilterList": vtfdFilterList,
777 "ForwardOperation": uint8(0x10), //VID investigation
778 "NumberOfEntries": oFsm.numVlanFilterEntries,
779 },
780 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000781 meInstance := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000782 oFsm.pAdaptFsm.commChan, meParams)
783 //accept also nil as (error) return value for writing to LastTx
784 // - this avoids misinterpretation of new received OMCI messages
785 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
786 // send shall return (dual format) error code that can be used here for immediate error treatment
787 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +0000788 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000789 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300790 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
791 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
792 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams.TpID
793
dbainbri4d3a0dc2020-12-02 00:33:42 +0000794 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300795 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000796 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000797 // setVid is assumed to be masked already by the caller to 12 bit
798 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] =
mpagenko01e726e2020-10-23 09:45:29 +0000799 uint16(oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams.SetVid)
mpagenko01e726e2020-10-23 09:45:29 +0000800 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300801
802 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
803 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
804 // new vlan associated with a different TP.
805 vtfdFilterList[0] = uint16(oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams.SetVid)
806 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000807
808 oFsm.numVlanFilterEntries++
809 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300810 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000811 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300812 "VlanFilterList": vtfdFilterList,
813 "ForwardOperation": uint8(0x10), //VID investigation
814 "NumberOfEntries": oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000815 },
816 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000817 meInstance := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000818 oFsm.pAdaptFsm.commChan, meParams)
819 //accept also nil as (error) return value for writing to LastTx
820 // - this avoids misinterpretation of new received OMCI messages
821 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
822 // send shall return (dual format) error code that can be used here for immediate error treatment
823 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +0000824 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000825 }
826 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +0000827 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000828 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000829 logger.Errorw(ctx, "VTFD create/set failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +0000830 log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +0000831 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
832 go func(a_pBaseFsm *fsm.FSM) {
833 _ = a_pBaseFsm.Event(vlanEvReset)
834 }(pConfigVlanStateBaseFsm)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000835 return
836 }
837 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000838 oFsm.requestEventOffset = 0 //0 offset for last flow-add activity
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300839 go func() {
840 tpID := oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams.TpID
dbainbri4d3a0dc2020-12-02 00:33:42 +0000841 errEvto := oFsm.performConfigEvtocdEntries(ctx, oFsm.configuredUniFlow)
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300842 //This is correct passing scenario
843 if errEvto == nil {
844 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
dbainbri4d3a0dc2020-12-02 00:33:42 +0000845 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300846 vlanID := oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow-1].VlanRuleParams.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +0000847 logger.Infow(ctx, "Setting multicast MEs for additional flows", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300848 "techProfile": tpID, "gemPort": gemPort,
849 "vlanID": vlanID, "configuredUniFlow": oFsm.configuredUniFlow})
850 //-1 is to use the last configured flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000851 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300852 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000853 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300854 log.Fields{"device-id": oFsm.deviceID})
855 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
856 }
857 }
858 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
859 }
860 }()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000861}
862
dbainbri4d3a0dc2020-12-02 00:33:42 +0000863func (oFsm *UniVlanConfigFsm) enterRemoveFlow(ctx context.Context, e *fsm.Event) {
mpagenko01e726e2020-10-23 09:45:29 +0000864 oFsm.mutexFlowParams.Lock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000865 logger.Debugw(ctx, "UniVlanConfigFsm - start removing the top remove-flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000866 "in state": e.FSM.Current(), "with last cookie": oFsm.uniRemoveFlowsSlice[0].cookie,
867 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000868
mpagenkofc4f56e2020-11-04 17:17:49 +0000869 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
870 loAllowSpecificOmciConfig := oFsm.pDeviceHandler.ReadyForSpecificOmciConfig
mpagenko01e726e2020-10-23 09:45:29 +0000871 loVlanEntryClear := uint8(0)
872 loVlanEntryRmPos := uint8(0x80) //with indication 'invalid' in bit 7
873 //shallow copy is sufficient as no reference variables are used within struct
874 loRuleParams := oFsm.uniRemoveFlowsSlice[0].vlanRuleParams
875 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000876 logger.Debugw(ctx, "UniVlanConfigFsm - remove-flow parameters are", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000877 "match vid": loRuleParams.MatchVid, "match Pcp": loRuleParams.MatchPcp,
878 "set vid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
879 "device-id": oFsm.deviceID})
880
881 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
882 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +0000883 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD removal required for transparent flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000884 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
885 } else {
886 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization and 're-copy'
887 if oFsm.numVlanFilterEntries == 1 {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300888 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + loRuleParams.TpID
mpagenko01e726e2020-10-23 09:45:29 +0000889 //only one active VLAN entry (hopefully the SetVID we want to remove - should be, but not verified ..)
890 // so we can just delete the VTFD entry
dbainbri4d3a0dc2020-12-02 00:33:42 +0000891 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD delete (no more vlan filters)",
mpagenko01e726e2020-10-23 09:45:29 +0000892 log.Fields{"current vlan list": oFsm.vlanFilterList,
893 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +0000894 loVlanEntryClear = 1 //full VlanFilter clear request
895 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
dbainbri4d3a0dc2020-12-02 00:33:42 +0000896 meInstance := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300897 oFsm.pAdaptFsm.commChan, vtfdID)
mpagenkofc4f56e2020-11-04 17:17:49 +0000898 oFsm.pLastTxMeInstance = meInstance
899 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000900 logger.Debugw(ctx, "UniVlanConfigFsm delete VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000901 "device-id": oFsm.deviceID, "device-state": deviceReasonMap[oFsm.pDeviceHandler.deviceReason]})
mpagenkofc4f56e2020-11-04 17:17:49 +0000902 }
mpagenko01e726e2020-10-23 09:45:29 +0000903 } else {
904 //many VTFD already should exists - find and remove the one concerned by the actual remove rule
905 // by updating the VTFD per set command with new valid list
dbainbri4d3a0dc2020-12-02 00:33:42 +0000906 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD removal of requested VLAN from the list on OMCI",
mpagenko01e726e2020-10-23 09:45:29 +0000907 log.Fields{"current vlan list": oFsm.vlanFilterList,
908 "set-vlan": loRuleParams.SetVid, "device-id": oFsm.deviceID})
909 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
910 if loRuleParams.SetVid == uint32(oFsm.vlanFilterList[i]) {
911 loVlanEntryRmPos = i
912 break //abort search
913 }
914 }
915 if loVlanEntryRmPos < cVtfdTableSize {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300916 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + loRuleParams.TpID
mpagenko01e726e2020-10-23 09:45:29 +0000917 //valid entry was found - to be eclipsed
918 loVlanEntryClear = 2 //VlanFilter remove request for a specific entry
919 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
920 if i < loVlanEntryRmPos {
921 vtfdFilterList[i] = oFsm.vlanFilterList[i] //copy original
922 } else if i < (cVtfdTableSize - 1) {
923 vtfdFilterList[i] = oFsm.vlanFilterList[i+1] //copy successor (including 0 elements)
924 } else {
925 vtfdFilterList[i] = 0 //set last byte if needed
926 }
927 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000928 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300929 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000930 "new vlan list": vtfdFilterList, "device-id": oFsm.deviceID})
931
mpagenkofc4f56e2020-11-04 17:17:49 +0000932 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300933 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
dbainbri4d3a0dc2020-12-02 00:33:42 +0000934 meInstance := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300935 oFsm.pAdaptFsm.commChan, vtfdID)
mpagenkofc4f56e2020-11-04 17:17:49 +0000936 oFsm.pLastTxMeInstance = meInstance
937 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000938 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000939 "device-id": oFsm.deviceID, "device-state": deviceReasonMap[oFsm.pDeviceHandler.deviceReason]})
mpagenko01e726e2020-10-23 09:45:29 +0000940 }
mpagenko01e726e2020-10-23 09:45:29 +0000941 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000942 logger.Warnw(ctx, "UniVlanConfigFsm: requested VLAN for removal not found in list - ignore and continue (no VTFD set)",
mpagenko01e726e2020-10-23 09:45:29 +0000943 log.Fields{"device-id": oFsm.deviceID})
944 }
945 }
946 if loVlanEntryClear > 0 {
mpagenkofc4f56e2020-11-04 17:17:49 +0000947 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
948 //waiting on response
dbainbri4d3a0dc2020-12-02 00:33:42 +0000949 err := oFsm.waitforOmciResponse(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +0000950 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000951 logger.Errorw(ctx, "VTFD delete/reset failed, aborting VlanConfig FSM!",
mpagenkofc4f56e2020-11-04 17:17:49 +0000952 log.Fields{"device-id": oFsm.deviceID})
953 // calling some FSM event must be decoupled
954 go func(a_pBaseFsm *fsm.FSM) {
955 _ = a_pBaseFsm.Event(vlanEvReset)
956 }(pConfigVlanStateBaseFsm)
957 return
958 }
mpagenko01e726e2020-10-23 09:45:29 +0000959 }
960
961 if loVlanEntryClear == 1 {
962 oFsm.vlanFilterList[0] = 0 //first entry is the only that can contain the previous only-one element
963 oFsm.numVlanFilterEntries = 0
964 } else if loVlanEntryClear == 2 {
965 // new VlanFilterList should be one entry smaller now - copy from last configured entry
966 // this loop now includes the 0 element on previous last valid entry
967 for i := uint8(0); i <= oFsm.numVlanFilterEntries; i++ {
968 oFsm.vlanFilterList[i] = vtfdFilterList[i]
969 }
970 oFsm.numVlanFilterEntries--
971 }
972 }
973 }
974
mpagenkofc4f56e2020-11-04 17:17:49 +0000975 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
dbainbri4d3a0dc2020-12-02 00:33:42 +0000976 go oFsm.removeEvtocdEntries(ctx, loRuleParams)
mpagenkofc4f56e2020-11-04 17:17:49 +0000977 } else {
978 // OMCI processing is not done, expectation is to have the ONU in some basic config state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +0000979 logger.Debugw(ctx, "UniVlanConfigFsm remove EVTOCD OMCI handling skipped based on device state", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +0000980 "device-id": oFsm.deviceID})
981 // calling some FSM event must be decoupled
982 go func(a_pBaseFsm *fsm.FSM) {
983 _ = a_pBaseFsm.Event(vlanEvRemFlowDone)
984 }(pConfigVlanStateBaseFsm)
985 }
mpagenkodff5dda2020-08-28 11:52:01 +0000986}
987
dbainbri4d3a0dc2020-12-02 00:33:42 +0000988func (oFsm *UniVlanConfigFsm) enterVlanCleanupDone(ctx context.Context, e *fsm.Event) {
989 logger.Debugw(ctx, "UniVlanConfigFsm - removing the removal data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000990 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000991
mpagenko01e726e2020-10-23 09:45:29 +0000992 oFsm.mutexFlowParams.Lock()
993 if len(oFsm.uniRemoveFlowsSlice) <= 1 {
994 oFsm.uniRemoveFlowsSlice = nil //reset the slice
dbainbri4d3a0dc2020-12-02 00:33:42 +0000995 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - last remove-flow deleted", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000996 "device-id": oFsm.deviceID})
997 } else {
998 //cut off the actual flow by slicing out the first element
999 oFsm.uniRemoveFlowsSlice = append(
1000 oFsm.uniRemoveFlowsSlice[:0],
1001 oFsm.uniRemoveFlowsSlice[1:]...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001002 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow deleted from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001003 "device-id": oFsm.deviceID})
1004 }
1005 oFsm.mutexFlowParams.Unlock()
1006
mpagenkofc4f56e2020-11-04 17:17:49 +00001007 oFsm.requestEventOffset = 1 //offset 1 for last flow-remove activity
mpagenko01e726e2020-10-23 09:45:29 +00001008 //return to the basic config verification state
mpagenkodff5dda2020-08-28 11:52:01 +00001009 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1010 if pConfigVlanStateAFsm != nil {
1011 // obviously calling some FSM event here directly does not work - so trying to decouple it ...
1012 go func(a_pAFsm *AdapterFsm) {
1013 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001014 _ = a_pAFsm.pFsm.Event(vlanEvFlowDataRemoved)
mpagenkodff5dda2020-08-28 11:52:01 +00001015 }
1016 }(pConfigVlanStateAFsm)
1017 }
1018}
1019
dbainbri4d3a0dc2020-12-02 00:33:42 +00001020func (oFsm *UniVlanConfigFsm) enterResetting(ctx context.Context, e *fsm.Event) {
1021 logger.Debugw(ctx, "UniVlanConfigFsm resetting", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001022
1023 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1024 if pConfigVlanStateAFsm != nil {
1025 // abort running message processing
1026 fsmAbortMsg := Message{
1027 Type: TestMsg,
1028 Data: TestMessage{
1029 TestMessageVal: AbortMessageProcessing,
1030 },
1031 }
1032 pConfigVlanStateAFsm.commChan <- fsmAbortMsg
1033
1034 //try to restart the FSM to 'disabled', decouple event transfer
1035 go func(a_pAFsm *AdapterFsm) {
1036 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301037 _ = a_pAFsm.pFsm.Event(vlanEvRestart)
mpagenkodff5dda2020-08-28 11:52:01 +00001038 }
1039 }(pConfigVlanStateAFsm)
1040 }
1041}
1042
dbainbri4d3a0dc2020-12-02 00:33:42 +00001043func (oFsm *UniVlanConfigFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
1044 logger.Debugw(ctx, "UniVlanConfigFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001045 oFsm.pLastTxMeInstance = nil
mpagenkodff5dda2020-08-28 11:52:01 +00001046 if oFsm.pDeviceHandler != nil {
mpagenko2418ab02020-11-12 12:58:06 +00001047 //TODO: to clarify with improved error treatment for VlanConfigFsm (timeout,reception) errors
1048 // current code removes the complete FSM including all flow/rule configuration done so far
1049 // this might be a bit to much, it would require fully new flow config from rwCore (at least on OnuDown/up)
1050 // maybe a more sophisticated approach is possible without clearing the data
1051 if oFsm.clearPersistency {
1052 //permanently remove possibly stored persistent data
1053 if len(oFsm.uniVlanFlowParamsSlice) > 0 {
1054 var emptySlice = make([]uniVlanFlowParams, 0)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001055 _ = oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID, &emptySlice) //ignore errors
mpagenko2418ab02020-11-12 12:58:06 +00001056 }
1057 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001058 logger.Debugw(ctx, "UniVlanConfigFsm persistency data not cleared", log.Fields{"device-id": oFsm.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001059 }
1060 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001061 go oFsm.pDeviceHandler.RemoveVlanFilterFsm(ctx, oFsm.pOnuUniPort)
mpagenkodff5dda2020-08-28 11:52:01 +00001062 }
1063}
1064
dbainbri4d3a0dc2020-12-02 00:33:42 +00001065func (oFsm *UniVlanConfigFsm) processOmciVlanMessages(ctx context.Context) { //ctx context.Context?
1066 logger.Debugw(ctx, "Start UniVlanConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001067loop:
1068 for {
mpagenkodff5dda2020-08-28 11:52:01 +00001069 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00001070 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001071 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +05301072 message, ok := <-oFsm.pAdaptFsm.commChan
1073 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001074 logger.Info(ctx, "UniVlanConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301075 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
1076 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1077 break loop
1078 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001079 logger.Debugw(ctx, "UniVlanConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301080
1081 switch message.Type {
1082 case TestMsg:
1083 msg, _ := message.Data.(TestMessage)
1084 if msg.TestMessageVal == AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001085 logger.Infow(ctx, "UniVlanConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001086 break loop
1087 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001088 logger.Warnw(ctx, "UniVlanConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Himani Chawla4d908332020-08-31 12:30:20 +05301089 case OMCI:
1090 msg, _ := message.Data.(OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001091 oFsm.handleOmciVlanConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301092 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001093 logger.Warn(ctx, "UniVlanConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301094 "message.Type": message.Type})
mpagenkodff5dda2020-08-28 11:52:01 +00001095 }
1096 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001097 logger.Infow(ctx, "End UniVlanConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001098}
1099
dbainbri4d3a0dc2020-12-02 00:33:42 +00001100func (oFsm *UniVlanConfigFsm) handleOmciVlanConfigMessage(ctx context.Context, msg OmciMessage) {
1101 logger.Debugw(ctx, "Rx OMCI UniVlanConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001102 "msgType": msg.OmciMsg.MessageType})
1103
1104 switch msg.OmciMsg.MessageType {
1105 case omci.CreateResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001106 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001107 if err := oFsm.handleOmciCreateResponseMessage(ctx, msg.OmciPacket); err != nil {
1108 logger.Warnw(ctx, "CreateResponse handling aborted", log.Fields{"err": err})
mpagenkodff5dda2020-08-28 11:52:01 +00001109 return
1110 }
mpagenkodff5dda2020-08-28 11:52:01 +00001111 } //CreateResponseType
1112 case omci.SetResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001113 { //leave that here as direct code as most often used
mpagenkodff5dda2020-08-28 11:52:01 +00001114 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1115 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001116 logger.Errorw(ctx, "Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001117 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001118 return
1119 }
1120 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1121 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001122 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001123 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001124 return
1125 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001126 logger.Debugw(ctx, "UniVlanConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkodff5dda2020-08-28 11:52:01 +00001127 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001128 logger.Errorw(ctx, "UniVlanConfigFsm Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001129 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
mpagenkodff5dda2020-08-28 11:52:01 +00001130 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1131 return
1132 }
mpagenko01e726e2020-10-23 09:45:29 +00001133 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1134 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1135 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001136 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "MulticastOperationsProfile":
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001137 { // let the MultiEntity config proceed by stopping the wait function
mpagenkodff5dda2020-08-28 11:52:01 +00001138 oFsm.omciMIdsResponseReceived <- true
1139 }
1140 }
1141 }
1142 } //SetResponseType
mpagenko01e726e2020-10-23 09:45:29 +00001143 case omci.DeleteResponseType:
1144 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001145 if err := oFsm.handleOmciDeleteResponseMessage(ctx, msg.OmciPacket); err != nil {
1146 logger.Warnw(ctx, "DeleteResponse handling aborted", log.Fields{"err": err})
mpagenko01e726e2020-10-23 09:45:29 +00001147 return
1148 }
1149 } //DeleteResponseType
mpagenkodff5dda2020-08-28 11:52:01 +00001150 default:
1151 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001152 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00001153 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001154 return
1155 }
1156 }
1157}
1158
dbainbri4d3a0dc2020-12-02 00:33:42 +00001159func (oFsm *UniVlanConfigFsm) handleOmciCreateResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00001160 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeCreateResponse)
1161 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001162 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001163 log.Fields{"device-id": oFsm.deviceID})
1164 return fmt.Errorf("omci msg layer could not be detected for CreateResponse for device-id %x",
1165 oFsm.deviceID)
1166 }
1167 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
1168 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001169 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001170 log.Fields{"device-id": oFsm.deviceID})
1171 return fmt.Errorf("omci msg layer could not be assigned for CreateResponse for device-id %x",
1172 oFsm.deviceID)
1173 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001174 logger.Debugw(ctx, "UniVlanConfigFsm CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001175 if msgObj.Result != me.Success && msgObj.Result != me.InstanceExists {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001176 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"device-id": oFsm.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00001177 "Error": msgObj.Result})
1178 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1179 return fmt.Errorf("omci CreateResponse Error for device-id %x",
1180 oFsm.deviceID)
1181 }
1182 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1183 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1184 // to satisfy StaticCodeAnalysis I had to move the small processing into a separate method :-(
1185 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001186 case "VlanTaggingFilterData", "MulticastOperationsProfile",
1187 "MulticastSubscriberConfigInfo", "MacBridgePortConfigurationData",
1188 "ExtendedVlanTaggingOperationConfigurationData":
mpagenko01e726e2020-10-23 09:45:29 +00001189 {
1190 if oFsm.pAdaptFsm.pFsm.Current() == vlanStConfigVtfd {
1191 // Only if CreateResponse is received from first flow entry - let the FSM proceed ...
1192 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigVtfd)
1193 } else { // let the MultiEntity config proceed by stopping the wait function
1194 oFsm.omciMIdsResponseReceived <- true
1195 }
1196 }
1197 }
1198 }
1199 return nil
1200}
1201
dbainbri4d3a0dc2020-12-02 00:33:42 +00001202func (oFsm *UniVlanConfigFsm) handleOmciDeleteResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00001203 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeDeleteResponse)
1204 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001205 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001206 log.Fields{"device-id": oFsm.deviceID})
1207 return fmt.Errorf("omci msg layer could not be detected for DeleteResponse for device-id %x",
1208 oFsm.deviceID)
1209 }
1210 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
1211 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001212 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001213 log.Fields{"device-id": oFsm.deviceID})
1214 return fmt.Errorf("omci msg layer could not be assigned for DeleteResponse for device-id %x",
1215 oFsm.deviceID)
1216 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001217 logger.Debugw(ctx, "UniVlanConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko01e726e2020-10-23 09:45:29 +00001218 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001219 logger.Errorw(ctx, "UniVlanConfigFsm - Omci DeleteResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001220 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1221 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1222 return fmt.Errorf("omci DeleteResponse Error for device-id %x",
1223 oFsm.deviceID)
1224 }
1225 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1226 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1227 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001228 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData":
mpagenko01e726e2020-10-23 09:45:29 +00001229 { // let the MultiEntity config proceed by stopping the wait function
1230 oFsm.omciMIdsResponseReceived <- true
1231 }
1232 }
1233 }
1234 return nil
1235}
1236
dbainbri4d3a0dc2020-12-02 00:33:42 +00001237func (oFsm *UniVlanConfigFsm) performConfigEvtocdEntries(ctx context.Context, aFlowEntryNo uint8) error {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001238 if aFlowEntryNo == 0 {
1239 // EthType set only at first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00001240 // EVTOCD ME is expected to exist at this point already from MIB-Download (with AssociationType/Pointer)
1241 // we need to extend the configuration by EthType definition and, to be sure, downstream 'inverse' mode
dbainbri4d3a0dc2020-12-02 00:33:42 +00001242 logger.Debugw(ctx, "UniVlanConfigFsm Tx Create::EVTOCD", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00001243 "EntitytId": strconv.FormatInt(int64(oFsm.evtocdID), 16),
1244 "i/oEthType": strconv.FormatInt(int64(cDefaultTpid), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001245 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001246 associationType := 2 // default to uniPPTP
1247 if oFsm.pOnuUniPort.portType == uniVEIP {
1248 associationType = 10
1249 }
1250 // Create the EVTOCD ME
mpagenkodff5dda2020-08-28 11:52:01 +00001251 meParams := me.ParamData{
1252 EntityID: oFsm.evtocdID,
1253 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001254 "InputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
1255 "OutputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
1256 "DownstreamMode": uint8(cDefaultDownstreamMode),
1257 "AssociationType": uint8(associationType),
1258 "AssociatedMePointer": oFsm.pOnuUniPort.entityID,
mpagenkodff5dda2020-08-28 11:52:01 +00001259 },
1260 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001261 meInstance := oFsm.pOmciCC.sendCreateEvtocdVar(context.TODO(), ConstDefaultOmciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001262 oFsm.pAdaptFsm.commChan, meParams)
1263 //accept also nil as (error) return value for writing to LastTx
1264 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001265 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001266
1267 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001268 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001269 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001270 logger.Errorw(ctx, "Evtocd create failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001271 log.Fields{"device-id": oFsm.deviceID})
1272 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1273 return fmt.Errorf("evtocd create failed %s, error %s", oFsm.deviceID, err)
1274 }
1275
1276 // Set the EVTOCD ME default params
1277 meParams = me.ParamData{
1278 EntityID: oFsm.evtocdID,
1279 Attributes: me.AttributeValueMap{
1280 "InputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
1281 "OutputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
1282 "DownstreamMode": uint8(cDefaultDownstreamMode),
1283 },
1284 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001285 meInstance = oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001286 oFsm.pAdaptFsm.commChan, meParams)
1287 //accept also nil as (error) return value for writing to LastTx
1288 // - this avoids misinterpretation of new received OMCI messages
1289 oFsm.pLastTxMeInstance = meInstance
1290
1291 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001292 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001293 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001294 logger.Errorw(ctx, "Evtocd set TPID failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001295 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301296 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001297 return fmt.Errorf("evtocd set TPID failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00001298 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001299 } //first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00001300
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001301 oFsm.mutexFlowParams.Lock()
mpagenko8b07c1b2020-11-26 10:36:31 +00001302 if uint8(len(oFsm.uniVlanFlowParamsSlice)) < aFlowEntryNo {
1303 //possibly the entry is not valid anymore based on intermediate delete requests
1304 //just a basic protection ...
1305 oFsm.mutexFlowParams.Unlock()
1306 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1307 go func(a_pAFsm *AdapterFsm) {
1308 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1309 }(pConfigVlanStateAFsm)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001310 return nil
mpagenko8b07c1b2020-11-26 10:36:31 +00001311 }
1312
mpagenko01e726e2020-10-23 09:45:29 +00001313 if oFsm.uniVlanFlowParamsSlice[aFlowEntryNo].VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00001314 //transparent transmission required
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001315 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001316 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged transparent rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001317 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001318 sliceEvtocdRule := make([]uint8, 16)
1319 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1320 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1321 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1322 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1323 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1324
1325 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1326 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
1327 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1328 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1329 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1330
1331 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1332 0<<cTreatTTROffset| // Do not pop any tags
1333 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1334 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1335 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1336
1337 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1338 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
1339 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1340 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
1341
1342 meParams := me.ParamData{
1343 EntityID: oFsm.evtocdID,
1344 Attributes: me.AttributeValueMap{
1345 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1346 },
1347 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001348 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001349 oFsm.pAdaptFsm.commChan, meParams)
1350 //accept also nil as (error) return value for writing to LastTx
1351 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001352 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001353
1354 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001355 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001356 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001357 logger.Errorw(ctx, "Evtocd set transparent singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001358 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301359 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001360 return fmt.Errorf("evtocd set transparent singletagged rule failed %s, error %s", oFsm.deviceID, err)
1361
mpagenkodff5dda2020-08-28 11:52:01 +00001362 }
1363 } else {
1364 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
1365 if oFsm.acceptIncrementalEvtoOption {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001366 matchPcp := oFsm.uniVlanFlowParamsSlice[aFlowEntryNo].VlanRuleParams.MatchPcp
1367 matchVid := oFsm.uniVlanFlowParamsSlice[aFlowEntryNo].VlanRuleParams.MatchVid
1368 setPcp := oFsm.uniVlanFlowParamsSlice[aFlowEntryNo].VlanRuleParams.SetPcp
1369 setVid := oFsm.uniVlanFlowParamsSlice[aFlowEntryNo].VlanRuleParams.SetVid
mpagenkodff5dda2020-08-28 11:52:01 +00001370 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001371 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged translation rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001372 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001373 sliceEvtocdRule := make([]uint8, 16)
1374 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1375 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1376 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1377 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1378 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1379
1380 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
mpagenko01e726e2020-10-23 09:45:29 +00001381 oFsm.uniVlanFlowParamsSlice[aFlowEntryNo].VlanRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
1382 oFsm.uniVlanFlowParamsSlice[aFlowEntryNo].VlanRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
mpagenkodff5dda2020-08-28 11:52:01 +00001383 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1384 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1385
1386 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
mpagenko01e726e2020-10-23 09:45:29 +00001387 oFsm.uniVlanFlowParamsSlice[aFlowEntryNo].VlanRuleParams.TagsToRemove<<cTreatTTROffset| // either 1 or 0
mpagenkodff5dda2020-08-28 11:52:01 +00001388 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1389 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1390 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1391
1392 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
mpagenko01e726e2020-10-23 09:45:29 +00001393 oFsm.uniVlanFlowParamsSlice[aFlowEntryNo].VlanRuleParams.SetPcp<<cTreatPrioOffset| // as configured in flow
1394 oFsm.uniVlanFlowParamsSlice[aFlowEntryNo].VlanRuleParams.SetVid<<cTreatVidOffset| //as configured in flow
mpagenkodff5dda2020-08-28 11:52:01 +00001395 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001396 oFsm.mutexFlowParams.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001397
1398 meParams := me.ParamData{
1399 EntityID: oFsm.evtocdID,
1400 Attributes: me.AttributeValueMap{
1401 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1402 },
1403 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001404 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001405 oFsm.pAdaptFsm.commChan, meParams)
1406 //accept also nil as (error) return value for writing to LastTx
1407 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001408 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001409
1410 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001411 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001412 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001413 logger.Errorw(ctx, "Evtocd set singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001414 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301415 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001416 return fmt.Errorf("evtocd set singletagged translation rule failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00001417 }
1418 } else {
1419 //not transparent and not acceptIncrementalEvtoOption untagged/priotagged->singletagged
1420 { // just for local var's
1421 // this defines stacking scenario: untagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00001422 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD untagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001423 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001424 sliceEvtocdRule := make([]uint8, 16)
1425 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1426 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1427 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1428 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1429 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1430
1431 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1432 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
1433 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1434 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1435 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1436
1437 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1438 0<<cTreatTTROffset| // Do not pop any tags
1439 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1440 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1441 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1442
1443 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1444 0<<cTreatPrioOffset| // vlan prio set to 0
1445 // (as done in Py code, maybe better option would be setPcp here, which still could be 0?)
mpagenko01e726e2020-10-23 09:45:29 +00001446 oFsm.uniVlanFlowParamsSlice[aFlowEntryNo].VlanRuleParams.SetVid<<cTreatVidOffset| // Outer VID don't care
mpagenkodff5dda2020-08-28 11:52:01 +00001447 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
1448
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001449 oFsm.mutexFlowParams.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001450 meParams := me.ParamData{
1451 EntityID: oFsm.evtocdID,
1452 Attributes: me.AttributeValueMap{
1453 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1454 },
1455 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001456 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001457 oFsm.pAdaptFsm.commChan, meParams)
1458 //accept also nil as (error) return value for writing to LastTx
1459 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001460 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001461
1462 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001463 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001464 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001465 logger.Errorw(ctx, "Evtocd set untagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001466 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301467 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001468 return fmt.Errorf("evtocd set untagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
1469
mpagenkodff5dda2020-08-28 11:52:01 +00001470 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001471 } // just for local var's
mpagenkodff5dda2020-08-28 11:52:01 +00001472 { // just for local var's
1473 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00001474 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD priotagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001475 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001476 sliceEvtocdRule := make([]uint8, 16)
1477 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1478 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1479 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1480 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1481 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1482
1483 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1484 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
1485 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
1486 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1487 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1488
1489 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1490 1<<cTreatTTROffset| // pop the prio-tag
1491 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1492 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1493 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1494
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001495 oFsm.mutexFlowParams.Lock()
mpagenkodff5dda2020-08-28 11:52:01 +00001496 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1497 cCopyPrioFromInner<<cTreatPrioOffset| // vlan copy from PrioTag
1498 // (as done in Py code, maybe better option would be setPcp here, which still could be PrioCopy?)
mpagenko01e726e2020-10-23 09:45:29 +00001499 oFsm.uniVlanFlowParamsSlice[aFlowEntryNo].VlanRuleParams.SetVid<<cTreatVidOffset| // Outer VID as configured
mpagenkodff5dda2020-08-28 11:52:01 +00001500 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001501 oFsm.mutexFlowParams.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001502
1503 meParams := me.ParamData{
1504 EntityID: oFsm.evtocdID,
1505 Attributes: me.AttributeValueMap{
1506 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1507 },
1508 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001509 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001510 oFsm.pAdaptFsm.commChan, meParams)
1511 //accept also nil as (error) return value for writing to LastTx
1512 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001513 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001514
1515 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001516 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001517 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001518 logger.Errorw(ctx, "Evtocd set priotagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001519 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301520 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001521 return fmt.Errorf("evtocd set priotagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
1522
mpagenkodff5dda2020-08-28 11:52:01 +00001523 }
1524 } //just for local var's
1525 }
1526 }
1527
mpagenkofc4f56e2020-11-04 17:17:49 +00001528 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001529 logger.Debugw(ctx, "EVTOCD set loop finished", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001530 oFsm.configuredUniFlow++ // one (more) flow configured
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001531 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00001532}
1533
dbainbri4d3a0dc2020-12-02 00:33:42 +00001534func (oFsm *UniVlanConfigFsm) removeEvtocdEntries(ctx context.Context, aRuleParams uniVlanRuleParams) {
mpagenko01e726e2020-10-23 09:45:29 +00001535 // configured Input/Output TPID is not modified again - no influence if no filter is applied
1536 if aRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
1537 //transparent transmission was set
1538 //perhaps the config is not needed for removal,
1539 // but the specific InnerTpid setting is removed in favor of the real default forwarding rule
dbainbri4d3a0dc2020-12-02 00:33:42 +00001540 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset to default single tagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001541 "device-id": oFsm.deviceID})
1542 sliceEvtocdRule := make([]uint8, 16)
1543 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1544 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1545 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1546 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1547 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1548
1549 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1550 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
1551 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1552 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1553 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1554
1555 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1556 0<<cTreatTTROffset| // Do not pop any tags
1557 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1558 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1559 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1560
1561 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1562 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
1563 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1564 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
1565
1566 meParams := me.ParamData{
1567 EntityID: oFsm.evtocdID,
1568 Attributes: me.AttributeValueMap{
1569 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1570 },
1571 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001572 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00001573 oFsm.pAdaptFsm.commChan, meParams)
1574 //accept also nil as (error) return value for writing to LastTx
1575 // - this avoids misinterpretation of new received OMCI messages
1576 oFsm.pLastTxMeInstance = meInstance
1577
1578 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001579 err := oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001580 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001581 logger.Errorw(ctx, "Evtocd reset singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001582 log.Fields{"device-id": oFsm.deviceID})
1583 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1584 return
1585 }
1586 } else {
1587 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
1588 if oFsm.acceptIncrementalEvtoOption {
1589 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001590 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear single tagged translation rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001591 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
1592 sliceEvtocdRule := make([]uint8, 16)
1593 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1594 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1595 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1596 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1597 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1598
1599 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1600 aRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
1601 aRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
1602 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1603 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1604
1605 // delete indication for the indicated Filter
1606 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
1607 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
1608
1609 meParams := me.ParamData{
1610 EntityID: oFsm.evtocdID,
1611 Attributes: me.AttributeValueMap{
1612 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1613 },
1614 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001615 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00001616 oFsm.pAdaptFsm.commChan, meParams)
1617 //accept also nil as (error) return value for writing to LastTx
1618 // - this avoids misinterpretation of new received OMCI messages
1619 oFsm.pLastTxMeInstance = meInstance
1620
1621 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001622 err := oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001623 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001624 logger.Errorw(ctx, "Evtocd clear singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001625 log.Fields{"device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
1626 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1627 return
1628 }
1629 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001630 // VOL-3685
1631 // NOTE: With ALPHA ONUs it was seen that just resetting a particular entry in the EVTOCD table
1632 // and re-configuring a new entry would not work. The old entry is removed and new entry is created
1633 // indeed, but the traffic landing upstream would carry old vlan sometimes.
1634 // This is only a WORKAROUND which basically deletes the entire EVTOCD ME and re-creates it again
1635 // later when the flow is being re-installed.
1636 // Of course this is applicable to case only where single service (or single tcont) is in use and
1637 // there is only one service vlan (oFsm.acceptIncrementalEvtoOption is false in this case).
1638 // Interstingly this problem has not been observed in multi-tcont (or multi-service) scenario (in
1639 // which case the oFsm.acceptIncrementalEvtoOption is set to true).
1640 if oFsm.configuredUniFlow == 0 && !oFsm.acceptIncrementalEvtoOption {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001641 logger.Debugw(ctx, "UniVlanConfigFsm Tx Remove::EVTOCD", log.Fields{"device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001642 // When there are no more EVTOCD vlan configurations on the ONU and acceptIncrementalEvtoOption
1643 // is not enabled, delete the EVTOCD ME.
mpagenko01e726e2020-10-23 09:45:29 +00001644 meParams := me.ParamData{
1645 EntityID: oFsm.evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00001646 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001647 meInstance := oFsm.pOmciCC.sendDeleteEvtocd(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00001648 oFsm.pAdaptFsm.commChan, meParams)
1649 //accept also nil as (error) return value for writing to LastTx
1650 // - this avoids misinterpretation of new received OMCI messages
1651 oFsm.pLastTxMeInstance = meInstance
1652
1653 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001654 err := oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001655 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001656 logger.Errorw(ctx, "Evtocd delete rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001657 log.Fields{"device-id": oFsm.deviceID})
1658 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1659 return
1660 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001661 } else {
1662 // NOTE : We should ideally never ether this section when oFsm.acceptIncrementalEvtoOption is set to false
1663 // This is true for only ATT/DT workflow
dbainbri4d3a0dc2020-12-02 00:33:42 +00001664 logger.Debugw(ctx, "UniVlanConfigFsm: Remove EVTOCD set operation",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001665 log.Fields{"configured-flow": oFsm.configuredUniFlow, "incremental-evto": oFsm.acceptIncrementalEvtoOption})
1666 //not transparent and not acceptIncrementalEvtoOption: untagged/priotagged->singletagged
1667 { // just for local var's
1668 // this defines stacking scenario: untagged->singletagged
1669 //TODO!! in theory there could be different rules running in setting different PCP/VID'S
1670 // for untagged/priotagged, last rule wins (and remains the only one), maybe that should be
1671 // checked already at flow-add (and rejected) - to be observed if such is possible in Voltha
1672 // delete now assumes there is only one such rule!
dbainbri4d3a0dc2020-12-02 00:33:42 +00001673 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset untagged rule to default", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001674 "device-id": oFsm.deviceID})
1675 sliceEvtocdRule := make([]uint8, 16)
1676 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1677 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1678 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1679 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1680 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00001681
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001682 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1683 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
1684 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1685 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1686 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00001687
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001688 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1689 0<<cTreatTTROffset| // Do not pop any tags
1690 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1691 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1692 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
mpagenko01e726e2020-10-23 09:45:29 +00001693
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001694 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1695 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
1696 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1697 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
mpagenko01e726e2020-10-23 09:45:29 +00001698
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001699 meParams := me.ParamData{
1700 EntityID: oFsm.evtocdID,
1701 Attributes: me.AttributeValueMap{
1702 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1703 },
1704 }
1705 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(context.TODO(), ConstDefaultOmciTimeout, true,
1706 oFsm.pAdaptFsm.commChan, meParams)
1707 //accept also nil as (error) return value for writing to LastTx
1708 // - this avoids misinterpretation of new received OMCI messages
1709 oFsm.pLastTxMeInstance = meInstance
1710
1711 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001712 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001713 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001714 logger.Errorw(ctx, "Evtocd reset untagged rule to default failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001715 log.Fields{"device-id": oFsm.deviceID})
1716 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1717 return
1718 }
1719 } // just for local var's
1720 { // just for local var's
1721 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00001722 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD delete priotagged rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001723 "device-id": oFsm.deviceID})
1724 sliceEvtocdRule := make([]uint8, 16)
1725 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1726 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1727 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1728 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1729 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1730
1731 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1732 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
1733 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
1734 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1735 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1736
1737 // delete indication for the indicated Filter
1738 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
1739 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
1740
1741 meParams := me.ParamData{
1742 EntityID: oFsm.evtocdID,
1743 Attributes: me.AttributeValueMap{
1744 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1745 },
1746 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001747 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001748 oFsm.pAdaptFsm.commChan, meParams)
1749 //accept also nil as (error) return value for writing to LastTx
1750 // - this avoids misinterpretation of new received OMCI messages
1751 oFsm.pLastTxMeInstance = meInstance
1752
1753 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001754 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001755 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001756 logger.Errorw(ctx, "Evtocd delete priotagged rule failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001757 log.Fields{"device-id": oFsm.deviceID})
1758 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1759 return
1760 }
mpagenko01e726e2020-10-23 09:45:29 +00001761 }
1762 } //just for local var's
1763 }
1764 }
1765
mpagenkofc4f56e2020-11-04 17:17:49 +00001766 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001767 logger.Debugw(ctx, "EVTOCD filter remove loop finished", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001768 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRemFlowDone)
1769}
1770
dbainbri4d3a0dc2020-12-02 00:33:42 +00001771func (oFsm *UniVlanConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenkodff5dda2020-08-28 11:52:01 +00001772 select {
Himani Chawla26e555c2020-08-31 12:30:20 +05301773 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenkodff5dda2020-08-28 11:52:01 +00001774 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00001775 // logger.Infow(ctx,"LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001776 case <-time.After(30 * time.Second): //AS FOR THE OTHER OMCI FSM's
dbainbri4d3a0dc2020-12-02 00:33:42 +00001777 logger.Warnw(ctx, "UniVlanConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001778 return fmt.Errorf("uniVlanConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00001779 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05301780 if success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001781 logger.Debug(ctx, "UniVlanConfigFsm multi entity response received")
mpagenkodff5dda2020-08-28 11:52:01 +00001782 return nil
1783 }
1784 // should not happen so far
dbainbri4d3a0dc2020-12-02 00:33:42 +00001785 logger.Warnw(ctx, "UniVlanConfigFsm multi entity response error", log.Fields{"for device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001786 return fmt.Errorf("uniVlanConfigFsm multi entity responseError %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00001787 }
1788}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001789
dbainbri4d3a0dc2020-12-02 00:33:42 +00001790func (oFsm *UniVlanConfigFsm) performSettingMulticastME(ctx context.Context, tpID uint16, multicastGemPortID uint16, vlanID uint32) error {
1791 logger.Debugw(ctx, "Setting Multicast MEs", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001792 "multicastGemPortID": multicastGemPortID, "vlanID": vlanID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001793 errCreateMOP := oFsm.performCreatingMulticastOperationProfile(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001794 if errCreateMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001795 logger.Errorw(ctx, "MulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001796 log.Fields{"device-id": oFsm.deviceID})
1797 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1798 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMOP)
1799 }
1800
dbainbri4d3a0dc2020-12-02 00:33:42 +00001801 errSettingMOP := oFsm.performSettingMulticastOperationProfile(ctx, multicastGemPortID, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001802 if errSettingMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001803 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001804 log.Fields{"device-id": oFsm.deviceID})
1805 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1806 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errSettingMOP)
1807 }
1808
dbainbri4d3a0dc2020-12-02 00:33:42 +00001809 errCreateMSCI := oFsm.performCreatingMulticastSubscriberConfigInfo(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001810 if errCreateMSCI != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001811 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001812 log.Fields{"device-id": oFsm.deviceID})
1813 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1814 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMSCI)
1815 }
1816
1817 meParams := me.ParamData{
1818 EntityID: macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo),
1819 Attributes: me.AttributeValueMap{
1820 "BridgeIdPointer": macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo),
1821 "PortNum": 0xf0, //fixed unique ANI side indication
1822 "TpType": 6, //MCGemIWTP
1823 "TpPointer": multicastGemPortID,
1824 },
1825 }
1826 meInstance := oFsm.pOmciCC.sendCreateMBPConfigDataVar(context.TODO(), ConstDefaultOmciTimeout, true,
1827 oFsm.pAdaptFsm.commChan, meParams)
1828 //accept also nil as (error) return value for writing to LastTx
1829 // - this avoids misinterpretation of new received OMCI messages
1830 oFsm.pLastTxMeInstance = meInstance
dbainbri4d3a0dc2020-12-02 00:33:42 +00001831 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001832 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001833 logger.Errorw(ctx, "CreateMBPConfigData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001834 log.Fields{"device-id": oFsm.deviceID, "MBPConfigDataID": macBridgeServiceProfileEID})
1835 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1836 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, err)
1837 }
1838
1839 // ==> Start creating VTFD for mcast vlan
1840
1841 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1842 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
1843 mcastVtfdID := macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo)
1844
dbainbri4d3a0dc2020-12-02 00:33:42 +00001845 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD for mcast", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001846 "EntitytId": strconv.FormatInt(int64(mcastVtfdID), 16), "mcastVlanID": vlanID,
1847 "in state": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
1848 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
1849
1850 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
1851 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
1852 // new vlan associated with a different TP.
1853 vtfdFilterList[0] = uint16(vlanID)
1854
1855 meParams = me.ParamData{
1856 EntityID: mcastVtfdID,
1857 Attributes: me.AttributeValueMap{
1858 "VlanFilterList": vtfdFilterList,
1859 "ForwardOperation": uint8(0x10), //VID investigation
1860 "NumberOfEntries": oFsm.numVlanFilterEntries,
1861 },
1862 }
1863 meInstance = oFsm.pOmciCC.sendCreateVtfdVar(context.TODO(), ConstDefaultOmciTimeout, true,
1864 oFsm.pAdaptFsm.commChan, meParams)
1865 oFsm.pLastTxMeInstance = meInstance
dbainbri4d3a0dc2020-12-02 00:33:42 +00001866 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001867 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001868 logger.Errorw(ctx, "CreateMcastVlanFilterData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001869 log.Fields{"device-id": oFsm.deviceID, "mcastVtfdID": mcastVtfdID})
1870 _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
1871 return fmt.Errorf("createMcastVlanFilterData responseError %s, error %s", oFsm.deviceID, err)
1872 }
1873
1874 return nil
1875}
1876
dbainbri4d3a0dc2020-12-02 00:33:42 +00001877func (oFsm *UniVlanConfigFsm) performCreatingMulticastSubscriberConfigInfo(ctx context.Context) error {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001878 instID, err := oFsm.pDeviceHandler.getUniPortMEEntityID(oFsm.pOnuUniPort.portNo)
1879 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001880 logger.Errorw(ctx, "error fetching uni port me instance",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001881 log.Fields{"device-id": oFsm.deviceID, "portNo": oFsm.pOnuUniPort.portNo})
1882 return err
1883 }
1884 meParams := me.ParamData{
1885 EntityID: instID,
1886 Attributes: me.AttributeValueMap{
1887 "MeType": 0,
1888 //Direct reference to the Operation profile
1889 //TODO ANI side used on UNI side, not the clearest option.
1890 "MulticastOperationsProfilePointer": macBridgePortAniEID + uint16(oFsm.pOnuUniPort.macBpNo),
1891 },
1892 }
1893 meInstance := oFsm.pOmciCC.sendCreateMulticastSubConfigInfoVar(context.TODO(), ConstDefaultOmciTimeout, true,
1894 oFsm.pAdaptFsm.commChan, meParams)
1895 //accept also nil as (error) return value for writing to LastTx
1896 // - this avoids misinterpretation of new received OMCI messages
1897 oFsm.pLastTxMeInstance = meInstance
1898 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001899 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001900 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001901 logger.Errorw(ctx, "CreateMulticastSubConfigInfo create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001902 log.Fields{"device-id": oFsm.deviceID, "MulticastSubConfigInfo": instID})
1903 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s", oFsm.deviceID)
1904 }
1905 return nil
1906}
1907
dbainbri4d3a0dc2020-12-02 00:33:42 +00001908func (oFsm *UniVlanConfigFsm) performCreatingMulticastOperationProfile(ctx context.Context) error {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001909 instID := macBridgePortAniEID + uint16(oFsm.pOnuUniPort.macBpNo)
1910 meParams := me.ParamData{
1911 EntityID: instID,
1912 Attributes: me.AttributeValueMap{
1913 "IgmpVersion": 2,
1914 "IgmpFunction": 0,
1915 //0 means false
1916 "ImmediateLeave": 0,
1917 "Robustness": 2,
1918 "QuerierIp": 0,
1919 "QueryInterval": 125,
1920 "QuerierMaxResponseTime": 100,
1921 "LastMemberResponseTime": 10,
1922 //0 means false
1923 "UnauthorizedJoinBehaviour": 0,
1924 },
1925 }
1926 meInstance := oFsm.pOmciCC.sendCreateMulticastOperationProfileVar(context.TODO(), ConstDefaultOmciTimeout, true,
1927 oFsm.pAdaptFsm.commChan, meParams)
1928 //accept also nil as (error) return value for writing to LastTx
1929 // - this avoids misinterpretation of new received OMCI messages
1930 oFsm.pLastTxMeInstance = meInstance
1931 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001932 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001933 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001934 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001935 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
1936 return fmt.Errorf("createMulticastOperationProfile responseError %s", oFsm.deviceID)
1937 }
1938 return nil
1939}
1940
dbainbri4d3a0dc2020-12-02 00:33:42 +00001941func (oFsm *UniVlanConfigFsm) performSettingMulticastOperationProfile(ctx context.Context, multicastGemPortID uint16, vlanID uint32) error {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001942 instID := macBridgePortAniEID + uint16(oFsm.pOnuUniPort.macBpNo)
1943 //TODO check that this is correct
1944 // Table control
1945 //setCtrl = 1
1946 //rowPartId = 0
1947 //test = 0
1948 //rowKey = 0
1949 tableCtrlStr := "0100000000000000"
1950 tableCtrl := AsByteSlice(tableCtrlStr)
1951 //TODO Building it as a Table, even though the attribute is `StringAttributeType`
1952 // see line 56 of multicastoperationsprofileframe.go, it's an error in the conversion.
1953 // FIXED 30/12/2020 Fixed for now with a local copy of multicastoperationsprofileframe.go in vendor/omci-lib-go
1954 // provided by Chip, needs upstreaming and version change.
1955 dynamicAccessCL := make([]uint8, 24)
1956 copy(dynamicAccessCL, tableCtrl)
1957 //Multicast GemPortId
1958 binary.BigEndian.PutUint16(dynamicAccessCL[2:], multicastGemPortID)
1959 // python version waits for installation of flows, see line 723 onward of
1960 // brcm_openomci_onu_handler.py
1961 binary.BigEndian.PutUint16(dynamicAccessCL[4:], uint16(vlanID))
1962 //Source IP all to 0
1963 binary.BigEndian.PutUint32(dynamicAccessCL[6:], IPToInt32(net.IPv4(0, 0, 0, 0)))
1964 //TODO start and end are hardcoded, get from TP
1965 // Destination IP address start of range
1966 binary.BigEndian.PutUint32(dynamicAccessCL[10:], IPToInt32(net.IPv4(225, 0, 0, 0)))
1967 // Destination IP address end of range
1968 binary.BigEndian.PutUint32(dynamicAccessCL[14:], IPToInt32(net.IPv4(239, 255, 255, 255)))
1969 //imputed group bandwidth
1970 binary.BigEndian.PutUint16(dynamicAccessCL[18:], 0)
1971
1972 meParams := me.ParamData{
1973 EntityID: instID,
1974 Attributes: me.AttributeValueMap{
1975 "DynamicAccessControlListTable": dynamicAccessCL,
1976 },
1977 }
1978 meInstance := oFsm.pOmciCC.sendSetMulticastOperationProfileVar(context.TODO(), ConstDefaultOmciTimeout, true,
1979 oFsm.pAdaptFsm.commChan, meParams)
1980 //accept also nil as (error) return value for writing to LastTx
1981 // - this avoids misinterpretation of new received OMCI messages
1982 oFsm.pLastTxMeInstance = meInstance
1983 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001984 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001985 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001986 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001987 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
1988 return fmt.Errorf("createMulticastOperationProfile responseError %s", oFsm.deviceID)
1989 }
1990 return nil
1991}