blob: 501324e54878f8bc4a6d483667853daf3b278447 [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 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400401 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
402 field.Value = &openflow_13.OfpOxmOfbField_UdpSrc{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800403 UdpSrc: uint32(val.(uint16)),
404 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400405 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
406 field.Value = &openflow_13.OfpOxmOfbField_UdpDst{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800407 UdpDst: uint32(val.(uint16)),
408 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400409 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
410 field.Value = &openflow_13.OfpOxmOfbField_VlanVid{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800411 VlanVid: uint32(val.(uint16)),
412 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400413 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
414 field.Value = &openflow_13.OfpOxmOfbField_VlanPcp{
Esin Karaman082a7012020-06-23 15:47:02 +0000415 VlanPcp: uint32(val.(uint8)),
416 }
Don Newton7fe70f72020-02-21 13:54:11 -0500417 case 200: // voltha-protos doesn't actually have a type for vlan_mask
khenaidoofcf0b8d2021-10-19 17:57:30 -0400418 field = openflow_13.OfpOxmOfbField{Type: openflow_13.OxmOfbFieldTypes(oxmMap["vlan_vid"])}
Don Newton7fe70f72020-02-21 13:54:11 -0500419 field.HasMask = true
khenaidoofcf0b8d2021-10-19 17:57:30 -0400420 ofpOxmField = openflow_13.OfpOxmField{
Don Newton7fe70f72020-02-21 13:54:11 -0500421 OxmClass: ofp.OFPXMCOpenflowBasic,
422 Field: &openflow_13.OfpOxmField_OfbField{OfbField: &field},
423 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400424 field.Value = &openflow_13.OfpOxmOfbField_VlanVid{
Don Newton7fe70f72020-02-21 13:54:11 -0500425 VlanVid: uint32(val.(uint16)),
426 }
427 vidMask := val.(uint16)
khenaidoofcf0b8d2021-10-19 17:57:30 -0400428 field.Mask = &openflow_13.OfpOxmOfbField_VlanVidMask{
Don Newton7fe70f72020-02-21 13:54:11 -0500429 VlanVidMask: uint32(vidMask),
430 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800431 }
Don Newton7fe70f72020-02-21 13:54:11 -0500432
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800433 oxmList = append(oxmList, &ofpOxmField)
434 }
435
Matteo Scandolo322c3082020-06-17 14:21:26 -0700436 responseRequired := false
437
438 if flowDeleteStrict.GetFlags() == ofp.OFPFFSendFlowRem {
439 responseRequired = true
440 }
441
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800442 // Construct request
443 flowUpdate := openflow_13.FlowTableUpdate{
444 Id: ofc.DeviceID,
khenaidoofcf0b8d2021-10-19 17:57:30 -0400445 FlowMod: &openflow_13.OfpFlowMod{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800446 Cookie: flowDeleteStrict.Cookie,
447 CookieMask: flowDeleteStrict.CookieMask,
448 TableId: uint32(flowDeleteStrict.TableId),
khenaidoofcf0b8d2021-10-19 17:57:30 -0400449 Command: openflow_13.OfpFlowModCommand_OFPFC_DELETE_STRICT,
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800450 IdleTimeout: uint32(flowDeleteStrict.IdleTimeout),
451 HardTimeout: uint32(flowDeleteStrict.HardTimeout),
452 Priority: uint32(flowDeleteStrict.Priority),
453 BufferId: flowDeleteStrict.BufferId,
454 OutPort: uint32(flowDeleteStrict.OutPort),
455 OutGroup: uint32(flowDeleteStrict.OutGroup),
456 Flags: uint32(flowDeleteStrict.Flags),
khenaidoofcf0b8d2021-10-19 17:57:30 -0400457 Match: &openflow_13.OfpMatch{
458 Type: openflow_13.OfpMatchType(flowDeleteStrict.Match.GetType()),
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800459 OxmFields: oxmList,
460 },
461 },
Manindere2af7e42020-12-04 11:46:26 +0530462 Xid: flowDeleteStrict.Xid,
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800463 }
464
465 if logger.V(log.DebugLevel) {
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000466 logger.Debugf(ctx, "FlowDeleteStrict being sent to Voltha",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800467 log.Fields{
468 "device-id": ofc.DeviceID,
Matteo Scandolof3a7d572021-11-29 15:36:19 -0800469 "flow-update": flowUpdate})
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800470 }
Matteo Scandolo936e2df2020-10-27 14:31:36 -0700471
Girish Kumar01e0c632020-08-10 16:48:56 +0000472 if _, err := volthaClient.UpdateLogicalDeviceFlowTable(log.WithSpanFromContext(context.Background(), ctx), &flowUpdate); err != nil {
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000473 logger.Errorw(ctx, "Error calling FlowDelete ",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800474 log.Fields{
475 "device-id": ofc.DeviceID,
476 "error": err})
Matteo Scandolo322c3082020-06-17 14:21:26 -0700477 return
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800478 }
Matteo Scandolo322c3082020-06-17 14:21:26 -0700479
480 if responseRequired {
481 response := ofp.NewFlowRemoved()
482
483 response.Cookie = flowDeleteStrict.Cookie
484 response.Priority = flowDeleteStrict.Priority
485 response.Reason = ofp.OFPRRDelete
486 response.Match = flowDeleteStrict.Match
487 response.IdleTimeout = flowDeleteStrict.IdleTimeout
488 response.HardTimeout = flowDeleteStrict.HardTimeout
489 response.Xid = flowDeleteStrict.Xid
490
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000491 err := ofc.SendMessage(ctx, response)
Matteo Scandolo322c3082020-06-17 14:21:26 -0700492 if err != nil {
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000493 logger.Errorw(ctx, "Error sending FlowRemoved to ONOS",
Matteo Scandolo322c3082020-06-17 14:21:26 -0700494 log.Fields{
495 "device-id": ofc.DeviceID,
496 "error": err})
497 }
498 }
499
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800500}