blob: f6f3584b5cf78e355052c8215cbfa361e873ee2c [file] [log] [blame]
Naveen Sampath04696f72022-06-13 15:19:14 +05301/*
2* Copyright 2022-present Open Networking Foundation
3* Licensed under the Apache License, Version 2.0 (the "License");
4* you may not use this file except in compliance with the License.
5* You may obtain a copy of the License at
6*
7* http://www.apache.org/licenses/LICENSE-2.0
8*
9* Unless required by applicable law or agreed to in writing, software
10* distributed under the License is distributed on an "AS IS" BASIS,
11* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12* See the License for the specific language governing permissions and
13* limitations under the License.
14 */
15
16package application
17
18import (
19 infraerrorcode "voltha-go-controller/internal/pkg/errorcodes/service"
20
21 "voltha-go-controller/internal/pkg/intf"
Tinoj Joseph1d108322022-07-13 10:07:39 +053022 "voltha-go-controller/log"
Naveen Sampath04696f72022-06-13 15:19:14 +053023)
24
25//Generic Framework to enabling all flow based event trigger and handling.
26//The eventMapper can be updated for dynamic func caller for future events
27
28//FlowEventType - Type of event enumeration
29type FlowEventType string
30
31//FlowEventHandler - Func prototype for flow event handling funcs
32type FlowEventHandler func(*FlowEvent, intf.FlowStatus)
33
34var eventMapper map[FlowEventType]FlowEventHandler
35
36const (
37 //EventTypeUsIgmpFlowAdded - Event type for IGMP US flow add
38 EventTypeUsIgmpFlowAdded FlowEventType = "USIgmpFlowAdded"
39 //EventTypeServiceFlowAdded - Event type for Service flow add
40 EventTypeServiceFlowAdded FlowEventType = "ServiceFlowAdded"
41 //EventTypeControlFlowAdded - Event type for Control flow add
42 EventTypeControlFlowAdded FlowEventType = "ControlFlowAdded"
43
44 //EventTypeDeviceFlowRemoved - Event type for Device flow del
45 EventTypeDeviceFlowRemoved FlowEventType = "DeviceFlowRemoved"
46 //EventTypeMcastFlowRemoved - Event type for Mcast flow del
47 EventTypeMcastFlowRemoved FlowEventType = "McastFlowRemoved"
48
49 //EventTypeServiceFlowRemoved - Event type for Service flow del
50 EventTypeServiceFlowRemoved FlowEventType = "ServiceFlowRemoved"
51 //EventTypeControlFlowRemoved - Event type for Control flow del
52 EventTypeControlFlowRemoved FlowEventType = "ControlFlowRemoved"
53)
54
55//FlowEvent - Event info for Flow event processing
56type FlowEvent struct {
57 eType FlowEventType
58 device string
59 cookie string
60 eventData interface{}
61}
62
63//InitEventFuncMapper - Initialization of flow event mapper
64func InitEventFuncMapper() {
65 eventMapper = map[FlowEventType]FlowEventHandler{
66 EventTypeUsIgmpFlowAdded: ProcessUsIgmpFlowAddEvent,
67 EventTypeControlFlowAdded: ProcessControlFlowAddEvent,
68 EventTypeServiceFlowAdded: ProcessServiceFlowAddEvent,
69 EventTypeControlFlowRemoved: ProcessControlFlowDelEvent,
70 EventTypeServiceFlowRemoved: ProcessServiceFlowDelEvent,
71 EventTypeDeviceFlowRemoved: ProcessDeviceFlowDelEvent,
72 EventTypeMcastFlowRemoved: ProcessMcastFlowDelEvent,
73 }
74}
75
76//ExecuteFlowEvent - Process flow based event triggers
77func ExecuteFlowEvent(vd *VoltDevice, cookie string, flowStatus intf.FlowStatus) bool {
78 var event interface{}
79
80 flowEventMap, err := vd.GetFlowEventRegister(flowStatus.FlowModType)
81 if err != nil {
82 logger.Debugw(ctx, "Flow event map does not exists", log.Fields{"flowMod": flowStatus.FlowModType, "Error": err})
83 return false
84 }
85 flowEventMap.MapLock.Lock()
86
87 if event, _ = flowEventMap.Get(cookie); event == nil {
88 logger.Debugw(ctx, "Event already processed or event not registered for the cookie", log.Fields{"Cookie": cookie})
89 flowEventMap.MapLock.Unlock()
90 return false
91 }
92 flowEventMap.Remove(cookie)
93 flowEventMap.MapLock.Unlock()
94 flowEvent := event.(*FlowEvent)
95 eventMapper[flowEvent.eType](flowEvent, flowStatus)
96 return true
97}
98
99//ProcessUsIgmpFlowAddEvent - Process Us Igmp Flow event trigger
100func ProcessUsIgmpFlowAddEvent(event *FlowEvent, flowStatus intf.FlowStatus) {
101
102 logger.Infow(ctx, "Processing Post Flow Add Event for US Igmp", log.Fields{"Cookie": event.cookie, "event": event})
103 vpv := event.eventData.(*VoltPortVnet)
104 if isFlowStatusSuccess(flowStatus.Status, true) {
105 vpv.services.Range(ReceiverUpInd)
106 } else {
107 vpv.IgmpFlowInstallFailure(event.cookie, flowStatus.Status, flowStatus.Reason)
108 }
109}
110
111//ProcessServiceFlowAddEvent - Process Service Flow event trigger
112func ProcessServiceFlowAddEvent(event *FlowEvent, flowStatus intf.FlowStatus) {
113
114 logger.Infow(ctx, "Processing Post Flow Add Event for Service", log.Fields{"Cookie": event.cookie, "event": event})
115 vs := event.eventData.(*VoltService)
116 if isFlowStatusSuccess(flowStatus.Status, true) {
117 vs.FlowInstallSuccess(event.cookie, flowStatus.AdditionalData)
118 } else {
119 vs.FlowInstallFailure(event.cookie, flowStatus.Status, flowStatus.Reason)
120 }
121}
122
123//ProcessControlFlowAddEvent - Process Control Flow event trigger
124func ProcessControlFlowAddEvent(event *FlowEvent, flowStatus intf.FlowStatus) {
125
126 logger.Infow(ctx, "Processing Post Flow Add Event for VPV", log.Fields{"Cookie": event.cookie, "event": event})
127 vpv := event.eventData.(*VoltPortVnet)
128 if !isFlowStatusSuccess(flowStatus.Status, true) {
129 vpv.FlowInstallFailure(event.cookie, flowStatus.Status, flowStatus.Reason)
130 }
131}
132
133//ProcessServiceFlowDelEvent - Process Service Flow event trigger
134func ProcessServiceFlowDelEvent(event *FlowEvent, flowStatus intf.FlowStatus) {
135
136 logger.Infow(ctx, "Processing Post Flow Remove Event for Service", log.Fields{"Cookie": event.cookie, "event": event})
137 vs := event.eventData.(*VoltService)
138 if isFlowStatusSuccess(flowStatus.Status, false) {
139 vs.FlowRemoveSuccess(event.cookie)
140 } else {
141 vs.FlowRemoveFailure(event.cookie, flowStatus.Status, flowStatus.Reason)
142 }
143}
144
145//ProcessControlFlowDelEvent - Process Control Flow event trigger
146func ProcessControlFlowDelEvent(event *FlowEvent, flowStatus intf.FlowStatus) {
147
148 logger.Infow(ctx, "Processing Post Flow Remove Event for VPV", log.Fields{"Cookie": event.cookie, "event": event})
149 vpv := event.eventData.(*VoltPortVnet)
150 if isFlowStatusSuccess(flowStatus.Status, false) {
151 vpv.FlowRemoveSuccess(event.cookie, event.device)
152 } else {
153 vpv.FlowRemoveFailure(event.cookie, event.device, flowStatus.Status, flowStatus.Reason)
154 }
155}
156
157//ProcessMcastFlowDelEvent - Process Control Flow event trigger
158func ProcessMcastFlowDelEvent(event *FlowEvent, flowStatus intf.FlowStatus) {
159
160 logger.Infow(ctx, "Processing Post Flow Remove Event for Mcast/Igmp", log.Fields{"Cookie": event.cookie, "event": event})
161 mvp := event.eventData.(*MvlanProfile)
162 if isFlowStatusSuccess(flowStatus.Status, false) {
163 mvp.FlowRemoveSuccess(event.cookie, event.device)
164 } else {
165 mvp.FlowRemoveFailure(event.cookie, event.device, flowStatus.Status, flowStatus.Reason)
166 }
167}
168
169//ProcessDeviceFlowDelEvent - Process Control Flow event trigger
170func ProcessDeviceFlowDelEvent(event *FlowEvent, flowStatus intf.FlowStatus) {
171
172 logger.Infow(ctx, "Processing Post Flow Remove Event for VNET", log.Fields{"Cookie": event.cookie, "event": event})
173 vnet := event.eventData.(*VoltVnet)
174 if isFlowStatusSuccess(flowStatus.Status, false) {
175 vnet.FlowRemoveSuccess(event.cookie, event.device)
176 } else {
177 vnet.FlowRemoveFailure(event.cookie, event.device, flowStatus.Status, flowStatus.Reason)
178 }
179}
180
181//TODO: Update the func or flowStatus struct once all flow status are based on NB error code
182func isFlowStatusSuccess(status uint32, flowAdd bool) bool {
183 result := false
184 errorCode := infraerrorcode.ErrorCode(status)
185
186 if errorCode == infraerrorcode.ErrOk {
187 result = true
188 } else if !flowAdd && errorCode == infraerrorcode.ErrNotExists {
189 result = true
190 }
191 return result
192}