blob: 181814a06bd426518688b95e904e1660981bdfb1 [file] [log] [blame]
David K. Bainbridge157bdab2020-01-16 14:38:05 -08001/*
2 Copyright 2020 the original author or authors.
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
17package openflow
18
19import (
20 "context"
Andrea Campanella30342622020-03-05 20:48:26 +010021 "encoding/binary"
Jonathan Hart60c5d772020-03-30 18:28:40 -070022 "net"
David K. Bainbridgee05cf0c2021-08-19 03:16:50 +000023
24 ofp "github.com/opencord/goloxi/of13"
25 "github.com/opencord/voltha-lib-go/v7/pkg/log"
26 "github.com/opencord/voltha-protos/v5/go/openflow_13"
David K. Bainbridge157bdab2020-01-16 14:38:05 -080027)
28
29var oxmMap = map[string]int32{
Don Newton7fe70f72020-02-21 13:54:11 -050030 "in_port": 0,
31 "in_phy_port": 1,
32 "metadata": 2,
33 "eth_dst": 3,
34 "eth_src": 4,
35 "eth_type": 5,
36 "vlan_vid": 6,
37 "vlan_pcp": 7,
38 "ip_dscp": 8,
39 "ip_ecn": 9,
40 "ip_proto": 10,
41 "ipv4_src": 11,
42 "ipv4_dst": 12,
43 "tcp_src": 13,
44 "tcp_dst": 14,
45 "udp_src": 15,
46 "udp_dst": 16,
47 "sctp_src": 17,
48 "sctp_dst": 18,
49 "icmpv4_type": 19,
50 "icmpv4_code": 20,
51 "arp_op": 21,
52 "arp_spa": 22,
53 "arp_tpa": 23,
54 "arp_sha": 24,
55 "arp_tha": 25,
56 "ipv6_src": 26,
57 "ipv6_dst": 27,
58 "ipv6_flabel": 28,
59 "icmpv6_type": 29,
60 "icmpv6_code": 30,
61 "ipv6_nd_target": 31,
62 "ipv6_nd_sll": 32,
63 "ipv6_nd_tll": 33,
64 "mpls_label": 34,
65 "mpls_tc": 35,
66 "mpls_bos": 36,
67 "pbb_isid": 37,
68 "tunnel_id": 38,
69 "ipv6_exthdr": 39,
70 "vlan_vid_masked": 200, //made up
David K. Bainbridge157bdab2020-01-16 14:38:05 -080071}
72
Rohan Agrawalc32d9932020-06-15 11:01:47 +000073func (ofc *OFConnection) handleFlowAdd(ctx context.Context, flowAdd *ofp.FlowAdd) {
Girish Kumar01e0c632020-08-10 16:48:56 +000074 span, ctx := log.CreateChildSpan(ctx, "openflow-flow-add")
75 defer span.Finish()
76
David K. Bainbridge157bdab2020-01-16 14:38:05 -080077 if logger.V(log.DebugLevel) {
Rohan Agrawalc32d9932020-06-15 11:01:47 +000078 logger.Debugw(ctx, "handleFlowAdd called",
David K. Bainbridge157bdab2020-01-16 14:38:05 -080079 log.Fields{
80 "device-id": ofc.DeviceID,
Matteo Scandolof3a7d572021-11-29 15:36:19 -080081 "flow": flowAdd})
David K. Bainbridge157bdab2020-01-16 14:38:05 -080082 }
83
David Bainbridgef8ce7d22020-04-08 12:49:41 -070084 volthaClient := ofc.VolthaClient.Get()
85 if volthaClient == nil {
Rohan Agrawalc32d9932020-06-15 11:01:47 +000086 logger.Errorw(ctx, "no-voltha-connection",
David K. Bainbridge9cb404e2020-01-28 14:32:29 -080087 log.Fields{"device-id": ofc.DeviceID})
88 return
89 }
90
David K. Bainbridge157bdab2020-01-16 14:38:05 -080091 // Construct the match
khenaidoofcf0b8d2021-10-19 17:57:30 -040092 var oxmList []*openflow_13.OfpOxmField
David K. Bainbridge157bdab2020-01-16 14:38:05 -080093 for _, oxmField := range flowAdd.Match.GetOxmList() {
94 name := oxmMap[oxmField.GetOXMName()]
95 val := oxmField.GetOXMValue()
khenaidoofcf0b8d2021-10-19 17:57:30 -040096 field := openflow_13.OfpOxmOfbField{Type: openflow_13.OxmOfbFieldTypes(name)}
97 ofpOxmField := openflow_13.OfpOxmField{
David K. Bainbridge157bdab2020-01-16 14:38:05 -080098 OxmClass: ofp.OFPXMCOpenflowBasic,
99 Field: &openflow_13.OfpOxmField_OfbField{OfbField: &field},
100 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400101 switch openflow_13.OxmOfbFieldTypes(name) {
102 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_IN_PORT:
103 field.Value = &openflow_13.OfpOxmOfbField_Port{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800104 Port: uint32(val.(ofp.Port)),
105 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400106 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_IN_PHY_PORT:
107 field.Value = &openflow_13.OfpOxmOfbField_PhysicalPort{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800108 PhysicalPort: val.(uint32),
109 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400110 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
111 field.Value = &openflow_13.OfpOxmOfbField_TableMetadata{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800112 TableMetadata: val.(uint64),
113 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400114 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
115 field.Value = &openflow_13.OfpOxmOfbField_EthType{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800116 EthType: uint32(val.(ofp.EthernetType)),
117 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400118 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
119 field.Value = &openflow_13.OfpOxmOfbField_IpProto{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800120 IpProto: uint32(val.(ofp.IpPrototype)),
121 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400122 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
123 field.Value = &openflow_13.OfpOxmOfbField_Ipv4Dst{
Jonathan Hart60c5d772020-03-30 18:28:40 -0700124 Ipv4Dst: binary.BigEndian.Uint32(val.(net.IP)),
125 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400126 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_ETH_DST:
127 field.Value = &openflow_13.OfpOxmOfbField_EthDst{
Gamze Abaka3e2b2ce2020-05-09 10:21:40 +0000128 EthDst: val.(net.HardwareAddr),
129 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400130 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_ETH_SRC:
131 field.Value = &openflow_13.OfpOxmOfbField_EthSrc{
ssiddiquidf20bf72021-08-23 14:00:56 +0530132 EthSrc: val.(net.HardwareAddr),
133 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400134 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
135 field.Value = &openflow_13.OfpOxmOfbField_UdpSrc{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800136 UdpSrc: uint32(val.(uint16)),
137 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400138 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
139 field.Value = &openflow_13.OfpOxmOfbField_UdpDst{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800140 UdpDst: uint32(val.(uint16)),
141 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400142 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
143 field.Value = &openflow_13.OfpOxmOfbField_VlanVid{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800144 VlanVid: uint32((val.(uint16) & 0xfff) | 0x1000),
145 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400146 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
147 field.Value = &openflow_13.OfpOxmOfbField_VlanPcp{
Gamze Abaka3e2b2ce2020-05-09 10:21:40 +0000148 VlanPcp: uint32(val.(uint8)),
149 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400150 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_MPLS_LABEL:
151 field.Value = &openflow_13.OfpOxmOfbField_MplsLabel{
ssiddiquidf20bf72021-08-23 14:00:56 +0530152 MplsLabel: val.(uint32),
153 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400154 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_MPLS_BOS:
155 field.Value = &openflow_13.OfpOxmOfbField_MplsBos{
ssiddiquidf20bf72021-08-23 14:00:56 +0530156 MplsBos: uint32(val.(uint8)),
157 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400158 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_MPLS_TC:
159 field.Value = &openflow_13.OfpOxmOfbField_MplsTc{
ssiddiquidf20bf72021-08-23 14:00:56 +0530160 MplsTc: val.(uint32),
161 }
Don Newton7fe70f72020-02-21 13:54:11 -0500162 case 200: // voltha-protos doesn't actually have a type for vlan_mask
khenaidoofcf0b8d2021-10-19 17:57:30 -0400163 field = openflow_13.OfpOxmOfbField{Type: openflow_13.OxmOfbFieldTypes(oxmMap["vlan_vid"])}
Don Newton7fe70f72020-02-21 13:54:11 -0500164 field.HasMask = true
khenaidoofcf0b8d2021-10-19 17:57:30 -0400165 ofpOxmField = openflow_13.OfpOxmField{
Don Newton7fe70f72020-02-21 13:54:11 -0500166 OxmClass: ofp.OFPXMCOpenflowBasic,
167 Field: &openflow_13.OfpOxmField_OfbField{OfbField: &field},
168 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400169 field.Value = &openflow_13.OfpOxmOfbField_VlanVid{
Don Newton7fe70f72020-02-21 13:54:11 -0500170 VlanVid: uint32(val.(uint16)),
171 }
172 vidMask := val.(uint16)
khenaidoofcf0b8d2021-10-19 17:57:30 -0400173 field.Mask = &openflow_13.OfpOxmOfbField_VlanVidMask{
Don Newton7fe70f72020-02-21 13:54:11 -0500174 VlanVidMask: uint32(vidMask),
175 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800176 }
177 oxmList = append(oxmList, &ofpOxmField)
178 }
179
180 // Construct the instructions
khenaidoofcf0b8d2021-10-19 17:57:30 -0400181 var instructions []*openflow_13.OfpInstruction
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800182 for _, ofpInstruction := range flowAdd.GetInstructions() {
183 instructionType := ofpInstruction.GetType()
khenaidoofcf0b8d2021-10-19 17:57:30 -0400184 instruction := openflow_13.OfpInstruction{Type: uint32(instructionType)}
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800185 switch instructionType {
186 case ofp.OFPITGotoTable:
187 instruction.Data = &openflow_13.OfpInstruction_GotoTable{
188 GotoTable: &openflow_13.OfpInstructionGotoTable{
189 TableId: uint32(ofpInstruction.(ofp.IInstructionGotoTable).GetTableId()),
190 },
191 }
192 case ofp.OFPITWriteMetadata:
193 instruction.Data = &openflow_13.OfpInstruction_WriteMetadata{
194 WriteMetadata: &openflow_13.OfpInstructionWriteMetadata{
195 Metadata: ofpInstruction.(ofp.IInstructionWriteMetadata).GetMetadata(),
196 MetadataMask: ofpInstruction.(ofp.IInstructionWriteMetadata).GetMetadataMask(),
197 },
198 }
199 case ofp.OFPITWriteActions:
200 var ofpActions []*openflow_13.OfpAction
201 for _, action := range ofpInstruction.(ofp.IInstructionWriteActions).GetActions() {
202 ofpActions = append(ofpActions, extractAction(action))
203 }
204 instruction.Data = &openflow_13.OfpInstruction_Actions{
205 Actions: &openflow_13.OfpInstructionActions{
206 Actions: ofpActions,
207 },
208 }
209 case ofp.OFPITApplyActions:
210 var ofpActions []*openflow_13.OfpAction
211 for _, action := range ofpInstruction.(ofp.IInstructionApplyActions).GetActions() {
212 ofpActions = append(ofpActions, extractAction(action))
213 }
214 instruction.Data = &openflow_13.OfpInstruction_Actions{
215 Actions: &openflow_13.OfpInstructionActions{
216 Actions: ofpActions,
217 },
218 }
219 case ofp.OFPITMeter:
220 instruction.Data = &openflow_13.OfpInstruction_Meter{
221 Meter: &openflow_13.OfpInstructionMeter{
222 MeterId: ofpInstruction.(ofp.IInstructionMeter).GetMeterId(),
223 },
224 }
225 }
226 instructions = append(instructions, &instruction)
227 }
228
229 // Construct the request
230 flowUpdate := openflow_13.FlowTableUpdate{
231 Id: ofc.DeviceID,
khenaidoofcf0b8d2021-10-19 17:57:30 -0400232 FlowMod: &openflow_13.OfpFlowMod{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800233 Cookie: flowAdd.Cookie,
234 CookieMask: flowAdd.CookieMask,
235 TableId: uint32(flowAdd.TableId),
khenaidoofcf0b8d2021-10-19 17:57:30 -0400236 Command: openflow_13.OfpFlowModCommand_OFPFC_ADD,
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800237 IdleTimeout: uint32(flowAdd.IdleTimeout),
238 HardTimeout: uint32(flowAdd.HardTimeout),
239 Priority: uint32(flowAdd.Priority),
240 BufferId: flowAdd.BufferId,
241 OutPort: uint32(flowAdd.OutPort),
242 OutGroup: uint32(flowAdd.OutGroup),
243 Flags: uint32(flowAdd.Flags),
khenaidoofcf0b8d2021-10-19 17:57:30 -0400244 Match: &openflow_13.OfpMatch{
245 Type: openflow_13.OfpMatchType(flowAdd.Match.GetType()),
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800246 OxmFields: oxmList,
247 },
248
249 Instructions: instructions,
250 },
Manindere2af7e42020-12-04 11:46:26 +0530251 Xid: flowAdd.Xid,
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800252 }
253 if logger.V(log.DebugLevel) {
David K. Bainbridgee05cf0c2021-08-19 03:16:50 +0000254 logger.Debugw(ctx, "FlowAdd being sent to Voltha",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800255 log.Fields{
David K. Bainbridgee05cf0c2021-08-19 03:16:50 +0000256 "device-id": ofc.DeviceID,
257 "flow-mod-object": flowUpdate,
258 })
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800259 }
Girish Kumar01e0c632020-08-10 16:48:56 +0000260 if _, err := volthaClient.UpdateLogicalDeviceFlowTable(log.WithSpanFromContext(context.Background(), ctx), &flowUpdate); err != nil {
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000261 logger.Errorw(ctx, "Error calling FlowAdd ",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800262 log.Fields{
263 "device-id": ofc.DeviceID,
264 "error": err})
Andrea Campanella30342622020-03-05 20:48:26 +0100265 // Report failure to controller
266 message := ofp.NewFlowModFailedErrorMsg()
267 message.SetXid(flowAdd.Xid)
268 message.SetCode(ofp.OFPFMFCBadCommand)
269 //OF 1.3
270 message.SetVersion(4)
271 bs := make([]byte, 2)
272 //OF 1.3
273 bs[0] = byte(4)
274 //Flow Mod
275 bs[1] = byte(14)
276 //Length of the message
277 length := make([]byte, 2)
278 binary.BigEndian.PutUint16(length, 56)
279 bs = append(bs, length...)
280 empty := []byte{0, 0, 0, 0}
281 bs = append(bs, empty...)
282 //Cookie of the Flow
283 cookie := make([]byte, 52)
284 binary.BigEndian.PutUint64(cookie, flowAdd.Cookie)
285 bs = append(bs, cookie...)
286 message.SetData(bs)
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000287 err := ofc.SendMessage(ctx, message)
Andrea Campanella30342622020-03-05 20:48:26 +0100288 if err != nil {
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000289 logger.Errorw(ctx, "Error reporting failure of FlowUpdate to controller",
Andrea Campanella30342622020-03-05 20:48:26 +0100290 log.Fields{
291 "device-id": ofc.DeviceID,
292 "error": err})
293 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800294 }
295}
296
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000297func (ofc *OFConnection) handleFlowMod(ctx context.Context, flowMod *ofp.FlowMod) {
Girish Kumar01e0c632020-08-10 16:48:56 +0000298 span, ctx := log.CreateChildSpan(ctx, "openflow-flow-modification")
299 defer span.Finish()
300
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800301 if logger.V(log.DebugLevel) {
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000302 logger.Debugw(ctx, "handleFlowMod called",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800303 log.Fields{
304 "device-id": ofc.DeviceID,
Matteo Scandolof3a7d572021-11-29 15:36:19 -0800305 "flow-mod": flowMod})
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800306 }
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000307 logger.Errorw(ctx, "handleFlowMod not implemented",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800308 log.Fields{"device-id": ofc.DeviceID})
309}
310
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000311func (ofc *OFConnection) handleFlowModStrict(ctx context.Context, flowModStrict *ofp.FlowModifyStrict) {
Girish Kumar01e0c632020-08-10 16:48:56 +0000312 span, ctx := log.CreateChildSpan(ctx, "openflow-flow-modification-strict")
313 defer span.Finish()
314
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800315 if logger.V(log.DebugLevel) {
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000316 logger.Debugw(ctx, "handleFlowModStrict called",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800317 log.Fields{
318 "device-id": ofc.DeviceID,
Matteo Scandolof3a7d572021-11-29 15:36:19 -0800319 "flow-mod-strict": flowModStrict})
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800320 }
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000321 logger.Error(ctx, "handleFlowModStrict not implemented",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800322 log.Fields{"device-id": ofc.DeviceID})
323}
324
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000325func (ofc *OFConnection) handleFlowDelete(ctx context.Context, flowDelete *ofp.FlowDelete) {
Girish Kumar01e0c632020-08-10 16:48:56 +0000326 span, ctx := log.CreateChildSpan(ctx, "openflow-flow-delete")
327 defer span.Finish()
328
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800329 if logger.V(log.DebugLevel) {
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000330 logger.Debugw(ctx, "handleFlowDelete called",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800331 log.Fields{
332 "device-id": ofc.DeviceID,
Matteo Scandolof3a7d572021-11-29 15:36:19 -0800333 "flow-delete": flowDelete})
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800334 }
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000335 logger.Error(ctx, "handleFlowDelete not implemented",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800336 log.Fields{"device-id": ofc.DeviceID})
337
338}
339
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000340func (ofc *OFConnection) handleFlowDeleteStrict(ctx context.Context, flowDeleteStrict *ofp.FlowDeleteStrict) {
Girish Kumar01e0c632020-08-10 16:48:56 +0000341 span, ctx := log.CreateChildSpan(ctx, "openflow-flow-delete-strict")
342 defer span.Finish()
343
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800344 if logger.V(log.DebugLevel) {
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000345 logger.Debugw(ctx, "handleFlowDeleteStrict called",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800346 log.Fields{
Matteo Scandolof3a7d572021-11-29 15:36:19 -0800347 "device-id": ofc.DeviceID,
348 "flow": flowDeleteStrict})
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800349 }
350
David Bainbridgef8ce7d22020-04-08 12:49:41 -0700351 volthaClient := ofc.VolthaClient.Get()
352 if volthaClient == nil {
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000353 logger.Errorw(ctx, "no-voltha-connection",
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800354 log.Fields{"device-id": ofc.DeviceID})
355 return
356 }
357
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800358 // Construct match
khenaidoofcf0b8d2021-10-19 17:57:30 -0400359 var oxmList []*openflow_13.OfpOxmField
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800360 for _, oxmField := range flowDeleteStrict.Match.GetOxmList() {
361 name := oxmMap[oxmField.GetOXMName()]
362 val := oxmField.GetOXMValue()
khenaidoofcf0b8d2021-10-19 17:57:30 -0400363 var ofpOxmField openflow_13.OfpOxmField
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800364 ofpOxmField.OxmClass = ofp.OFPXMCOpenflowBasic
khenaidoofcf0b8d2021-10-19 17:57:30 -0400365 var field openflow_13.OfpOxmOfbField
366 field.Type = openflow_13.OxmOfbFieldTypes(name)
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800367
368 var x openflow_13.OfpOxmField_OfbField
369 x.OfbField = &field
370 ofpOxmField.Field = &x
371
khenaidoofcf0b8d2021-10-19 17:57:30 -0400372 switch openflow_13.OxmOfbFieldTypes(name) {
373 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_IN_PORT:
374 field.Value = &openflow_13.OfpOxmOfbField_Port{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800375 Port: uint32(val.(ofp.Port)),
376 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400377 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_IN_PHY_PORT:
378 field.Value = &openflow_13.OfpOxmOfbField_PhysicalPort{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800379 PhysicalPort: val.(uint32),
380 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400381 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
382 field.Value = &openflow_13.OfpOxmOfbField_TableMetadata{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800383 TableMetadata: val.(uint64),
384 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400385 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
386 field.Value = &openflow_13.OfpOxmOfbField_EthType{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800387 EthType: uint32(val.(ofp.EthernetType)),
388 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400389 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
390 field.Value = &openflow_13.OfpOxmOfbField_IpProto{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800391 IpProto: uint32(val.(ofp.IpPrototype)),
392 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400393 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
394 field.Value = &openflow_13.OfpOxmOfbField_Ipv4Dst{
Jonathan Hart60c5d772020-03-30 18:28:40 -0700395 Ipv4Dst: binary.BigEndian.Uint32(val.(net.IP)),
396 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400397 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_ETH_DST:
398 field.Value = &openflow_13.OfpOxmOfbField_EthDst{
Esin Karaman082a7012020-06-23 15:47:02 +0000399 EthDst: val.(net.HardwareAddr),
400 }
Abhilash Laxmeshware6c42f02022-03-17 15:59:05 +0530401 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_ETH_SRC:
402 field.Value = &openflow_13.OfpOxmOfbField_EthSrc{
403 EthSrc: val.(net.HardwareAddr),
404 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400405 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
406 field.Value = &openflow_13.OfpOxmOfbField_UdpSrc{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800407 UdpSrc: uint32(val.(uint16)),
408 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400409 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
410 field.Value = &openflow_13.OfpOxmOfbField_UdpDst{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800411 UdpDst: uint32(val.(uint16)),
412 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400413 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
414 field.Value = &openflow_13.OfpOxmOfbField_VlanVid{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800415 VlanVid: uint32(val.(uint16)),
416 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400417 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
418 field.Value = &openflow_13.OfpOxmOfbField_VlanPcp{
Esin Karaman082a7012020-06-23 15:47:02 +0000419 VlanPcp: uint32(val.(uint8)),
420 }
Don Newton7fe70f72020-02-21 13:54:11 -0500421 case 200: // voltha-protos doesn't actually have a type for vlan_mask
khenaidoofcf0b8d2021-10-19 17:57:30 -0400422 field = openflow_13.OfpOxmOfbField{Type: openflow_13.OxmOfbFieldTypes(oxmMap["vlan_vid"])}
Don Newton7fe70f72020-02-21 13:54:11 -0500423 field.HasMask = true
khenaidoofcf0b8d2021-10-19 17:57:30 -0400424 ofpOxmField = openflow_13.OfpOxmField{
Don Newton7fe70f72020-02-21 13:54:11 -0500425 OxmClass: ofp.OFPXMCOpenflowBasic,
426 Field: &openflow_13.OfpOxmField_OfbField{OfbField: &field},
427 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400428 field.Value = &openflow_13.OfpOxmOfbField_VlanVid{
Don Newton7fe70f72020-02-21 13:54:11 -0500429 VlanVid: uint32(val.(uint16)),
430 }
431 vidMask := val.(uint16)
khenaidoofcf0b8d2021-10-19 17:57:30 -0400432 field.Mask = &openflow_13.OfpOxmOfbField_VlanVidMask{
Don Newton7fe70f72020-02-21 13:54:11 -0500433 VlanVidMask: uint32(vidMask),
434 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800435 }
Don Newton7fe70f72020-02-21 13:54:11 -0500436
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800437 oxmList = append(oxmList, &ofpOxmField)
438 }
439
Matteo Scandolo322c3082020-06-17 14:21:26 -0700440 responseRequired := false
441
442 if flowDeleteStrict.GetFlags() == ofp.OFPFFSendFlowRem {
443 responseRequired = true
444 }
445
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800446 // Construct request
447 flowUpdate := openflow_13.FlowTableUpdate{
448 Id: ofc.DeviceID,
khenaidoofcf0b8d2021-10-19 17:57:30 -0400449 FlowMod: &openflow_13.OfpFlowMod{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800450 Cookie: flowDeleteStrict.Cookie,
451 CookieMask: flowDeleteStrict.CookieMask,
452 TableId: uint32(flowDeleteStrict.TableId),
khenaidoofcf0b8d2021-10-19 17:57:30 -0400453 Command: openflow_13.OfpFlowModCommand_OFPFC_DELETE_STRICT,
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800454 IdleTimeout: uint32(flowDeleteStrict.IdleTimeout),
455 HardTimeout: uint32(flowDeleteStrict.HardTimeout),
456 Priority: uint32(flowDeleteStrict.Priority),
457 BufferId: flowDeleteStrict.BufferId,
458 OutPort: uint32(flowDeleteStrict.OutPort),
459 OutGroup: uint32(flowDeleteStrict.OutGroup),
460 Flags: uint32(flowDeleteStrict.Flags),
khenaidoofcf0b8d2021-10-19 17:57:30 -0400461 Match: &openflow_13.OfpMatch{
462 Type: openflow_13.OfpMatchType(flowDeleteStrict.Match.GetType()),
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800463 OxmFields: oxmList,
464 },
465 },
Manindere2af7e42020-12-04 11:46:26 +0530466 Xid: flowDeleteStrict.Xid,
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800467 }
468
469 if logger.V(log.DebugLevel) {
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000470 logger.Debugf(ctx, "FlowDeleteStrict being sent to Voltha",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800471 log.Fields{
472 "device-id": ofc.DeviceID,
Matteo Scandolof3a7d572021-11-29 15:36:19 -0800473 "flow-update": flowUpdate})
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800474 }
Matteo Scandolo936e2df2020-10-27 14:31:36 -0700475
Girish Kumar01e0c632020-08-10 16:48:56 +0000476 if _, err := volthaClient.UpdateLogicalDeviceFlowTable(log.WithSpanFromContext(context.Background(), ctx), &flowUpdate); err != nil {
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000477 logger.Errorw(ctx, "Error calling FlowDelete ",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800478 log.Fields{
479 "device-id": ofc.DeviceID,
480 "error": err})
Matteo Scandolo322c3082020-06-17 14:21:26 -0700481 return
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800482 }
Matteo Scandolo322c3082020-06-17 14:21:26 -0700483
484 if responseRequired {
485 response := ofp.NewFlowRemoved()
486
487 response.Cookie = flowDeleteStrict.Cookie
488 response.Priority = flowDeleteStrict.Priority
489 response.Reason = ofp.OFPRRDelete
490 response.Match = flowDeleteStrict.Match
491 response.IdleTimeout = flowDeleteStrict.IdleTimeout
492 response.HardTimeout = flowDeleteStrict.HardTimeout
493 response.Xid = flowDeleteStrict.Xid
494
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000495 err := ofc.SendMessage(ctx, response)
Matteo Scandolo322c3082020-06-17 14:21:26 -0700496 if err != nil {
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000497 logger.Errorw(ctx, "Error sending FlowRemoved to ONOS",
Matteo Scandolo322c3082020-06-17 14:21:26 -0700498 log.Fields{
499 "device-id": ofc.DeviceID,
500 "error": err})
501 }
502 }
503
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800504}