blob: a3914880cb21e293f1fe7717ab6b5e0ca4904f87 [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"
David K. Bainbridge157bdab2020-01-16 14:38:05 -080022 "encoding/json"
Jonathan Hart60c5d772020-03-30 18:28:40 -070023 "net"
David K. Bainbridgee05cf0c2021-08-19 03:16:50 +000024
25 ofp "github.com/opencord/goloxi/of13"
26 "github.com/opencord/voltha-lib-go/v7/pkg/log"
27 "github.com/opencord/voltha-protos/v5/go/openflow_13"
David K. Bainbridge157bdab2020-01-16 14:38:05 -080028)
29
30var oxmMap = map[string]int32{
Don Newton7fe70f72020-02-21 13:54:11 -050031 "in_port": 0,
32 "in_phy_port": 1,
33 "metadata": 2,
34 "eth_dst": 3,
35 "eth_src": 4,
36 "eth_type": 5,
37 "vlan_vid": 6,
38 "vlan_pcp": 7,
39 "ip_dscp": 8,
40 "ip_ecn": 9,
41 "ip_proto": 10,
42 "ipv4_src": 11,
43 "ipv4_dst": 12,
44 "tcp_src": 13,
45 "tcp_dst": 14,
46 "udp_src": 15,
47 "udp_dst": 16,
48 "sctp_src": 17,
49 "sctp_dst": 18,
50 "icmpv4_type": 19,
51 "icmpv4_code": 20,
52 "arp_op": 21,
53 "arp_spa": 22,
54 "arp_tpa": 23,
55 "arp_sha": 24,
56 "arp_tha": 25,
57 "ipv6_src": 26,
58 "ipv6_dst": 27,
59 "ipv6_flabel": 28,
60 "icmpv6_type": 29,
61 "icmpv6_code": 30,
62 "ipv6_nd_target": 31,
63 "ipv6_nd_sll": 32,
64 "ipv6_nd_tll": 33,
65 "mpls_label": 34,
66 "mpls_tc": 35,
67 "mpls_bos": 36,
68 "pbb_isid": 37,
69 "tunnel_id": 38,
70 "ipv6_exthdr": 39,
71 "vlan_vid_masked": 200, //made up
David K. Bainbridge157bdab2020-01-16 14:38:05 -080072}
73
Rohan Agrawalc32d9932020-06-15 11:01:47 +000074func (ofc *OFConnection) handleFlowAdd(ctx context.Context, flowAdd *ofp.FlowAdd) {
Girish Kumar01e0c632020-08-10 16:48:56 +000075 span, ctx := log.CreateChildSpan(ctx, "openflow-flow-add")
76 defer span.Finish()
77
David K. Bainbridge157bdab2020-01-16 14:38:05 -080078 if logger.V(log.DebugLevel) {
79 js, _ := json.Marshal(flowAdd)
Rohan Agrawalc32d9932020-06-15 11:01:47 +000080 logger.Debugw(ctx, "handleFlowAdd called",
David K. Bainbridge157bdab2020-01-16 14:38:05 -080081 log.Fields{
82 "device-id": ofc.DeviceID,
83 "params": js})
84 }
85
David Bainbridgef8ce7d22020-04-08 12:49:41 -070086 volthaClient := ofc.VolthaClient.Get()
87 if volthaClient == nil {
Rohan Agrawalc32d9932020-06-15 11:01:47 +000088 logger.Errorw(ctx, "no-voltha-connection",
David K. Bainbridge9cb404e2020-01-28 14:32:29 -080089 log.Fields{"device-id": ofc.DeviceID})
90 return
91 }
92
David K. Bainbridge157bdab2020-01-16 14:38:05 -080093 // Construct the match
khenaidoofcf0b8d2021-10-19 17:57:30 -040094 var oxmList []*openflow_13.OfpOxmField
David K. Bainbridge157bdab2020-01-16 14:38:05 -080095 for _, oxmField := range flowAdd.Match.GetOxmList() {
96 name := oxmMap[oxmField.GetOXMName()]
97 val := oxmField.GetOXMValue()
khenaidoofcf0b8d2021-10-19 17:57:30 -040098 field := openflow_13.OfpOxmOfbField{Type: openflow_13.OxmOfbFieldTypes(name)}
99 ofpOxmField := openflow_13.OfpOxmField{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800100 OxmClass: ofp.OFPXMCOpenflowBasic,
101 Field: &openflow_13.OfpOxmField_OfbField{OfbField: &field},
102 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400103 switch openflow_13.OxmOfbFieldTypes(name) {
104 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_IN_PORT:
105 field.Value = &openflow_13.OfpOxmOfbField_Port{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800106 Port: uint32(val.(ofp.Port)),
107 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400108 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_IN_PHY_PORT:
109 field.Value = &openflow_13.OfpOxmOfbField_PhysicalPort{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800110 PhysicalPort: val.(uint32),
111 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400112 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
113 field.Value = &openflow_13.OfpOxmOfbField_TableMetadata{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800114 TableMetadata: val.(uint64),
115 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400116 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
117 field.Value = &openflow_13.OfpOxmOfbField_EthType{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800118 EthType: uint32(val.(ofp.EthernetType)),
119 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400120 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
121 field.Value = &openflow_13.OfpOxmOfbField_IpProto{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800122 IpProto: uint32(val.(ofp.IpPrototype)),
123 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400124 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
125 field.Value = &openflow_13.OfpOxmOfbField_Ipv4Dst{
Jonathan Hart60c5d772020-03-30 18:28:40 -0700126 Ipv4Dst: binary.BigEndian.Uint32(val.(net.IP)),
127 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400128 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_ETH_DST:
129 field.Value = &openflow_13.OfpOxmOfbField_EthDst{
Gamze Abaka3e2b2ce2020-05-09 10:21:40 +0000130 EthDst: val.(net.HardwareAddr),
131 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400132 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_ETH_SRC:
133 field.Value = &openflow_13.OfpOxmOfbField_EthSrc{
ssiddiquidf20bf72021-08-23 14:00:56 +0530134 EthSrc: val.(net.HardwareAddr),
135 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400136 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
137 field.Value = &openflow_13.OfpOxmOfbField_UdpSrc{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800138 UdpSrc: uint32(val.(uint16)),
139 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400140 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
141 field.Value = &openflow_13.OfpOxmOfbField_UdpDst{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800142 UdpDst: uint32(val.(uint16)),
143 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400144 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
145 field.Value = &openflow_13.OfpOxmOfbField_VlanVid{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800146 VlanVid: uint32((val.(uint16) & 0xfff) | 0x1000),
147 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400148 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
149 field.Value = &openflow_13.OfpOxmOfbField_VlanPcp{
Gamze Abaka3e2b2ce2020-05-09 10:21:40 +0000150 VlanPcp: uint32(val.(uint8)),
151 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400152 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_MPLS_LABEL:
153 field.Value = &openflow_13.OfpOxmOfbField_MplsLabel{
ssiddiquidf20bf72021-08-23 14:00:56 +0530154 MplsLabel: val.(uint32),
155 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400156 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_MPLS_BOS:
157 field.Value = &openflow_13.OfpOxmOfbField_MplsBos{
ssiddiquidf20bf72021-08-23 14:00:56 +0530158 MplsBos: uint32(val.(uint8)),
159 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400160 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_MPLS_TC:
161 field.Value = &openflow_13.OfpOxmOfbField_MplsTc{
ssiddiquidf20bf72021-08-23 14:00:56 +0530162 MplsTc: val.(uint32),
163 }
Don Newton7fe70f72020-02-21 13:54:11 -0500164 case 200: // voltha-protos doesn't actually have a type for vlan_mask
khenaidoofcf0b8d2021-10-19 17:57:30 -0400165 field = openflow_13.OfpOxmOfbField{Type: openflow_13.OxmOfbFieldTypes(oxmMap["vlan_vid"])}
Don Newton7fe70f72020-02-21 13:54:11 -0500166 field.HasMask = true
khenaidoofcf0b8d2021-10-19 17:57:30 -0400167 ofpOxmField = openflow_13.OfpOxmField{
Don Newton7fe70f72020-02-21 13:54:11 -0500168 OxmClass: ofp.OFPXMCOpenflowBasic,
169 Field: &openflow_13.OfpOxmField_OfbField{OfbField: &field},
170 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400171 field.Value = &openflow_13.OfpOxmOfbField_VlanVid{
Don Newton7fe70f72020-02-21 13:54:11 -0500172 VlanVid: uint32(val.(uint16)),
173 }
174 vidMask := val.(uint16)
khenaidoofcf0b8d2021-10-19 17:57:30 -0400175 field.Mask = &openflow_13.OfpOxmOfbField_VlanVidMask{
Don Newton7fe70f72020-02-21 13:54:11 -0500176 VlanVidMask: uint32(vidMask),
177 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800178 }
179 oxmList = append(oxmList, &ofpOxmField)
180 }
181
182 // Construct the instructions
khenaidoofcf0b8d2021-10-19 17:57:30 -0400183 var instructions []*openflow_13.OfpInstruction
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800184 for _, ofpInstruction := range flowAdd.GetInstructions() {
185 instructionType := ofpInstruction.GetType()
khenaidoofcf0b8d2021-10-19 17:57:30 -0400186 instruction := openflow_13.OfpInstruction{Type: uint32(instructionType)}
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800187 switch instructionType {
188 case ofp.OFPITGotoTable:
189 instruction.Data = &openflow_13.OfpInstruction_GotoTable{
190 GotoTable: &openflow_13.OfpInstructionGotoTable{
191 TableId: uint32(ofpInstruction.(ofp.IInstructionGotoTable).GetTableId()),
192 },
193 }
194 case ofp.OFPITWriteMetadata:
195 instruction.Data = &openflow_13.OfpInstruction_WriteMetadata{
196 WriteMetadata: &openflow_13.OfpInstructionWriteMetadata{
197 Metadata: ofpInstruction.(ofp.IInstructionWriteMetadata).GetMetadata(),
198 MetadataMask: ofpInstruction.(ofp.IInstructionWriteMetadata).GetMetadataMask(),
199 },
200 }
201 case ofp.OFPITWriteActions:
202 var ofpActions []*openflow_13.OfpAction
203 for _, action := range ofpInstruction.(ofp.IInstructionWriteActions).GetActions() {
204 ofpActions = append(ofpActions, extractAction(action))
205 }
206 instruction.Data = &openflow_13.OfpInstruction_Actions{
207 Actions: &openflow_13.OfpInstructionActions{
208 Actions: ofpActions,
209 },
210 }
211 case ofp.OFPITApplyActions:
212 var ofpActions []*openflow_13.OfpAction
213 for _, action := range ofpInstruction.(ofp.IInstructionApplyActions).GetActions() {
214 ofpActions = append(ofpActions, extractAction(action))
215 }
216 instruction.Data = &openflow_13.OfpInstruction_Actions{
217 Actions: &openflow_13.OfpInstructionActions{
218 Actions: ofpActions,
219 },
220 }
221 case ofp.OFPITMeter:
222 instruction.Data = &openflow_13.OfpInstruction_Meter{
223 Meter: &openflow_13.OfpInstructionMeter{
224 MeterId: ofpInstruction.(ofp.IInstructionMeter).GetMeterId(),
225 },
226 }
227 }
228 instructions = append(instructions, &instruction)
229 }
230
231 // Construct the request
232 flowUpdate := openflow_13.FlowTableUpdate{
233 Id: ofc.DeviceID,
khenaidoofcf0b8d2021-10-19 17:57:30 -0400234 FlowMod: &openflow_13.OfpFlowMod{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800235 Cookie: flowAdd.Cookie,
236 CookieMask: flowAdd.CookieMask,
237 TableId: uint32(flowAdd.TableId),
khenaidoofcf0b8d2021-10-19 17:57:30 -0400238 Command: openflow_13.OfpFlowModCommand_OFPFC_ADD,
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800239 IdleTimeout: uint32(flowAdd.IdleTimeout),
240 HardTimeout: uint32(flowAdd.HardTimeout),
241 Priority: uint32(flowAdd.Priority),
242 BufferId: flowAdd.BufferId,
243 OutPort: uint32(flowAdd.OutPort),
244 OutGroup: uint32(flowAdd.OutGroup),
245 Flags: uint32(flowAdd.Flags),
khenaidoofcf0b8d2021-10-19 17:57:30 -0400246 Match: &openflow_13.OfpMatch{
247 Type: openflow_13.OfpMatchType(flowAdd.Match.GetType()),
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800248 OxmFields: oxmList,
249 },
250
251 Instructions: instructions,
252 },
Manindere2af7e42020-12-04 11:46:26 +0530253 Xid: flowAdd.Xid,
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800254 }
255 if logger.V(log.DebugLevel) {
David K. Bainbridgee05cf0c2021-08-19 03:16:50 +0000256 logger.Debugw(ctx, "FlowAdd being sent to Voltha",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800257 log.Fields{
David K. Bainbridgee05cf0c2021-08-19 03:16:50 +0000258 "device-id": ofc.DeviceID,
259 "flow-mod-object": flowUpdate,
260 })
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800261 }
Girish Kumar01e0c632020-08-10 16:48:56 +0000262 if _, err := volthaClient.UpdateLogicalDeviceFlowTable(log.WithSpanFromContext(context.Background(), ctx), &flowUpdate); err != nil {
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000263 logger.Errorw(ctx, "Error calling FlowAdd ",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800264 log.Fields{
265 "device-id": ofc.DeviceID,
266 "error": err})
Andrea Campanella30342622020-03-05 20:48:26 +0100267 // Report failure to controller
268 message := ofp.NewFlowModFailedErrorMsg()
269 message.SetXid(flowAdd.Xid)
270 message.SetCode(ofp.OFPFMFCBadCommand)
271 //OF 1.3
272 message.SetVersion(4)
273 bs := make([]byte, 2)
274 //OF 1.3
275 bs[0] = byte(4)
276 //Flow Mod
277 bs[1] = byte(14)
278 //Length of the message
279 length := make([]byte, 2)
280 binary.BigEndian.PutUint16(length, 56)
281 bs = append(bs, length...)
282 empty := []byte{0, 0, 0, 0}
283 bs = append(bs, empty...)
284 //Cookie of the Flow
285 cookie := make([]byte, 52)
286 binary.BigEndian.PutUint64(cookie, flowAdd.Cookie)
287 bs = append(bs, cookie...)
288 message.SetData(bs)
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000289 err := ofc.SendMessage(ctx, message)
Andrea Campanella30342622020-03-05 20:48:26 +0100290 if err != nil {
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000291 logger.Errorw(ctx, "Error reporting failure of FlowUpdate to controller",
Andrea Campanella30342622020-03-05 20:48:26 +0100292 log.Fields{
293 "device-id": ofc.DeviceID,
294 "error": err})
295 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800296 }
297}
298
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000299func (ofc *OFConnection) handleFlowMod(ctx context.Context, flowMod *ofp.FlowMod) {
Girish Kumar01e0c632020-08-10 16:48:56 +0000300 span, ctx := log.CreateChildSpan(ctx, "openflow-flow-modification")
301 defer span.Finish()
302
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800303 if logger.V(log.DebugLevel) {
304 js, _ := json.Marshal(flowMod)
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000305 logger.Debugw(ctx, "handleFlowMod called",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800306 log.Fields{
307 "device-id": ofc.DeviceID,
308 "flow-mod": js})
309 }
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000310 logger.Errorw(ctx, "handleFlowMod not implemented",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800311 log.Fields{"device-id": ofc.DeviceID})
312}
313
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000314func (ofc *OFConnection) handleFlowModStrict(ctx context.Context, flowModStrict *ofp.FlowModifyStrict) {
Girish Kumar01e0c632020-08-10 16:48:56 +0000315 span, ctx := log.CreateChildSpan(ctx, "openflow-flow-modification-strict")
316 defer span.Finish()
317
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800318 if logger.V(log.DebugLevel) {
319 js, _ := json.Marshal(flowModStrict)
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000320 logger.Debugw(ctx, "handleFlowModStrict called",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800321 log.Fields{
322 "device-id": ofc.DeviceID,
323 "flow-mod-strict": js})
324 }
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000325 logger.Error(ctx, "handleFlowModStrict not implemented",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800326 log.Fields{"device-id": ofc.DeviceID})
327}
328
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000329func (ofc *OFConnection) handleFlowDelete(ctx context.Context, flowDelete *ofp.FlowDelete) {
Girish Kumar01e0c632020-08-10 16:48:56 +0000330 span, ctx := log.CreateChildSpan(ctx, "openflow-flow-delete")
331 defer span.Finish()
332
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800333 if logger.V(log.DebugLevel) {
334 js, _ := json.Marshal(flowDelete)
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000335 logger.Debugw(ctx, "handleFlowDelete called",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800336 log.Fields{
337 "device-id": ofc.DeviceID,
338 "flow-delete": js})
339 }
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000340 logger.Error(ctx, "handleFlowDelete not implemented",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800341 log.Fields{"device-id": ofc.DeviceID})
342
343}
344
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000345func (ofc *OFConnection) handleFlowDeleteStrict(ctx context.Context, flowDeleteStrict *ofp.FlowDeleteStrict) {
Girish Kumar01e0c632020-08-10 16:48:56 +0000346 span, ctx := log.CreateChildSpan(ctx, "openflow-flow-delete-strict")
347 defer span.Finish()
348
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800349 if logger.V(log.DebugLevel) {
350 js, _ := json.Marshal(flowDeleteStrict)
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000351 logger.Debugw(ctx, "handleFlowDeleteStrict called",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800352 log.Fields{
353 "device-id": ofc.DeviceID,
354 "flow-delete-strict": js})
355 }
356
David Bainbridgef8ce7d22020-04-08 12:49:41 -0700357 volthaClient := ofc.VolthaClient.Get()
358 if volthaClient == nil {
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000359 logger.Errorw(ctx, "no-voltha-connection",
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800360 log.Fields{"device-id": ofc.DeviceID})
361 return
362 }
363
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800364 // Construct match
khenaidoofcf0b8d2021-10-19 17:57:30 -0400365 var oxmList []*openflow_13.OfpOxmField
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800366 for _, oxmField := range flowDeleteStrict.Match.GetOxmList() {
367 name := oxmMap[oxmField.GetOXMName()]
368 val := oxmField.GetOXMValue()
khenaidoofcf0b8d2021-10-19 17:57:30 -0400369 var ofpOxmField openflow_13.OfpOxmField
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800370 ofpOxmField.OxmClass = ofp.OFPXMCOpenflowBasic
khenaidoofcf0b8d2021-10-19 17:57:30 -0400371 var field openflow_13.OfpOxmOfbField
372 field.Type = openflow_13.OxmOfbFieldTypes(name)
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800373
374 var x openflow_13.OfpOxmField_OfbField
375 x.OfbField = &field
376 ofpOxmField.Field = &x
377
khenaidoofcf0b8d2021-10-19 17:57:30 -0400378 switch openflow_13.OxmOfbFieldTypes(name) {
379 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_IN_PORT:
380 field.Value = &openflow_13.OfpOxmOfbField_Port{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800381 Port: uint32(val.(ofp.Port)),
382 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400383 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_IN_PHY_PORT:
384 field.Value = &openflow_13.OfpOxmOfbField_PhysicalPort{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800385 PhysicalPort: val.(uint32),
386 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400387 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
388 field.Value = &openflow_13.OfpOxmOfbField_TableMetadata{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800389 TableMetadata: val.(uint64),
390 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400391 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
392 field.Value = &openflow_13.OfpOxmOfbField_EthType{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800393 EthType: uint32(val.(ofp.EthernetType)),
394 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400395 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
396 field.Value = &openflow_13.OfpOxmOfbField_IpProto{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800397 IpProto: uint32(val.(ofp.IpPrototype)),
398 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400399 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
400 field.Value = &openflow_13.OfpOxmOfbField_Ipv4Dst{
Jonathan Hart60c5d772020-03-30 18:28:40 -0700401 Ipv4Dst: binary.BigEndian.Uint32(val.(net.IP)),
402 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400403 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_ETH_DST:
404 field.Value = &openflow_13.OfpOxmOfbField_EthDst{
Esin Karaman082a7012020-06-23 15:47:02 +0000405 EthDst: val.(net.HardwareAddr),
406 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400407 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
408 field.Value = &openflow_13.OfpOxmOfbField_UdpSrc{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800409 UdpSrc: uint32(val.(uint16)),
410 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400411 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
412 field.Value = &openflow_13.OfpOxmOfbField_UdpDst{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800413 UdpDst: uint32(val.(uint16)),
414 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400415 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
416 field.Value = &openflow_13.OfpOxmOfbField_VlanVid{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800417 VlanVid: uint32(val.(uint16)),
418 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400419 case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
420 field.Value = &openflow_13.OfpOxmOfbField_VlanPcp{
Esin Karaman082a7012020-06-23 15:47:02 +0000421 VlanPcp: uint32(val.(uint8)),
422 }
Don Newton7fe70f72020-02-21 13:54:11 -0500423 case 200: // voltha-protos doesn't actually have a type for vlan_mask
khenaidoofcf0b8d2021-10-19 17:57:30 -0400424 field = openflow_13.OfpOxmOfbField{Type: openflow_13.OxmOfbFieldTypes(oxmMap["vlan_vid"])}
Don Newton7fe70f72020-02-21 13:54:11 -0500425 field.HasMask = true
khenaidoofcf0b8d2021-10-19 17:57:30 -0400426 ofpOxmField = openflow_13.OfpOxmField{
Don Newton7fe70f72020-02-21 13:54:11 -0500427 OxmClass: ofp.OFPXMCOpenflowBasic,
428 Field: &openflow_13.OfpOxmField_OfbField{OfbField: &field},
429 }
khenaidoofcf0b8d2021-10-19 17:57:30 -0400430 field.Value = &openflow_13.OfpOxmOfbField_VlanVid{
Don Newton7fe70f72020-02-21 13:54:11 -0500431 VlanVid: uint32(val.(uint16)),
432 }
433 vidMask := val.(uint16)
khenaidoofcf0b8d2021-10-19 17:57:30 -0400434 field.Mask = &openflow_13.OfpOxmOfbField_VlanVidMask{
Don Newton7fe70f72020-02-21 13:54:11 -0500435 VlanVidMask: uint32(vidMask),
436 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800437 }
Don Newton7fe70f72020-02-21 13:54:11 -0500438
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800439 oxmList = append(oxmList, &ofpOxmField)
440 }
441
Matteo Scandolo322c3082020-06-17 14:21:26 -0700442 responseRequired := false
443
444 if flowDeleteStrict.GetFlags() == ofp.OFPFFSendFlowRem {
445 responseRequired = true
446 }
447
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800448 // Construct request
449 flowUpdate := openflow_13.FlowTableUpdate{
450 Id: ofc.DeviceID,
khenaidoofcf0b8d2021-10-19 17:57:30 -0400451 FlowMod: &openflow_13.OfpFlowMod{
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800452 Cookie: flowDeleteStrict.Cookie,
453 CookieMask: flowDeleteStrict.CookieMask,
454 TableId: uint32(flowDeleteStrict.TableId),
khenaidoofcf0b8d2021-10-19 17:57:30 -0400455 Command: openflow_13.OfpFlowModCommand_OFPFC_DELETE_STRICT,
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800456 IdleTimeout: uint32(flowDeleteStrict.IdleTimeout),
457 HardTimeout: uint32(flowDeleteStrict.HardTimeout),
458 Priority: uint32(flowDeleteStrict.Priority),
459 BufferId: flowDeleteStrict.BufferId,
460 OutPort: uint32(flowDeleteStrict.OutPort),
461 OutGroup: uint32(flowDeleteStrict.OutGroup),
462 Flags: uint32(flowDeleteStrict.Flags),
khenaidoofcf0b8d2021-10-19 17:57:30 -0400463 Match: &openflow_13.OfpMatch{
464 Type: openflow_13.OfpMatchType(flowDeleteStrict.Match.GetType()),
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800465 OxmFields: oxmList,
466 },
467 },
Manindere2af7e42020-12-04 11:46:26 +0530468 Xid: flowDeleteStrict.Xid,
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800469 }
470
471 if logger.V(log.DebugLevel) {
472 flowUpdateJs, _ := json.Marshal(flowUpdate)
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000473 logger.Debugf(ctx, "FlowDeleteStrict being sent to Voltha",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800474 log.Fields{
475 "device-id": ofc.DeviceID,
476 "flow-update": flowUpdateJs})
477 }
Matteo Scandolo936e2df2020-10-27 14:31:36 -0700478
Girish Kumar01e0c632020-08-10 16:48:56 +0000479 if _, err := volthaClient.UpdateLogicalDeviceFlowTable(log.WithSpanFromContext(context.Background(), ctx), &flowUpdate); err != nil {
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000480 logger.Errorw(ctx, "Error calling FlowDelete ",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800481 log.Fields{
482 "device-id": ofc.DeviceID,
483 "error": err})
Matteo Scandolo322c3082020-06-17 14:21:26 -0700484 return
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800485 }
Matteo Scandolo322c3082020-06-17 14:21:26 -0700486
487 if responseRequired {
488 response := ofp.NewFlowRemoved()
489
490 response.Cookie = flowDeleteStrict.Cookie
491 response.Priority = flowDeleteStrict.Priority
492 response.Reason = ofp.OFPRRDelete
493 response.Match = flowDeleteStrict.Match
494 response.IdleTimeout = flowDeleteStrict.IdleTimeout
495 response.HardTimeout = flowDeleteStrict.HardTimeout
496 response.Xid = flowDeleteStrict.Xid
497
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000498 err := ofc.SendMessage(ctx, response)
Matteo Scandolo322c3082020-06-17 14:21:26 -0700499 if err != nil {
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000500 logger.Errorw(ctx, "Error sending FlowRemoved to ONOS",
Matteo Scandolo322c3082020-06-17 14:21:26 -0700501 log.Fields{
502 "device-id": ofc.DeviceID,
503 "error": err})
504 }
505 }
506
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800507}