blob: 53ec8c9725837f52269f82db052e112c643f5e59 [file] [log] [blame]
Don Newton98fd8812019-09-23 15:15:02 -04001/*
2 Copyright 2017 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"
21 "encoding/json"
Don Newtone0d34a82019-11-14 10:58:06 -050022 "log"
23
24 ofp "github.com/donNewtonAlpha/goloxi/of13"
Don Newtonb437c6f2019-12-18 11:51:57 -050025 "github.com/opencord/voltha-protos/v2/go/openflow_13"
26 pb "github.com/opencord/voltha-protos/v2/go/voltha"
Don Newton98fd8812019-09-23 15:15:02 -040027)
28
29var oxmMap = map[string]int32{
30 "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}
71
72func handleFlowAdd(flowAdd *ofp.FlowAdd, deviceId string) {
73 js, _ := json.Marshal(flowAdd)
74 log.Printf("handleFlowAdd called with %s", js)
75
76 var flowUpdate openflow_13.FlowTableUpdate
77 flowUpdate.Id = deviceId
78 var flowMod pb.OfpFlowMod
79 flowMod.Cookie = flowAdd.Cookie
80 flowMod.CookieMask = flowAdd.CookieMask
81 flowMod.TableId = uint32(flowAdd.TableId)
Don Newtonb437c6f2019-12-18 11:51:57 -050082 //flowMod.Command = pb.OfpFlowModCommand_OFPFC_ADD
83 flowMod.Command = 0
Don Newton98fd8812019-09-23 15:15:02 -040084 flowMod.IdleTimeout = uint32(flowAdd.IdleTimeout)
85 flowMod.HardTimeout = uint32(flowAdd.HardTimeout)
86 flowMod.Priority = uint32(flowAdd.Priority)
87 flowMod.BufferId = flowAdd.BufferId
88 flowMod.OutPort = uint32(flowAdd.OutPort)
89 flowMod.OutGroup = uint32(flowAdd.OutGroup)
90 flowMod.Flags = uint32(flowAdd.Flags)
Don Newtonb437c6f2019-12-18 11:51:57 -050091 js, _ = json.Marshal(flowMod)
92 log.Printf("HANDLE FLOW ADD FLOW_MOD %s", js)
Don Newton98fd8812019-09-23 15:15:02 -040093 inMatch := flowAdd.Match
94 var flowMatch pb.OfpMatch
95 flowMatch.Type = pb.OfpMatchType(inMatch.GetType())
96 var oxmList []*pb.OfpOxmField
97 inOxmList := inMatch.GetOxmList()
98 for i := 0; i < len(inOxmList); i++ {
99 oxmField := inOxmList[i]
100 j, _ := json.Marshal(oxmField)
101
102 name := oxmMap[oxmField.GetOXMName()]
103 log.Printf("\n\n\n %s %d %s\n\n\n", j, name, oxmField.GetOXMName())
104
105 val := oxmField.GetOXMValue()
106 var ofpOxmField pb.OfpOxmField
107 ofpOxmField.OxmClass = ofp.OFPXMCOpenflowBasic
108 var field pb.OfpOxmOfbField
109
110 field.Type = pb.OxmOfbFieldTypes(name)
111 log.Println("****\nFieldType: " + openflow_13.OxmOfbFieldTypes_name[name] + "\n\n\n\n")
112
113 var x openflow_13.OfpOxmField_OfbField
114 x.OfbField = &field
115 ofpOxmField.Field = &x
116
117 switch pb.OxmOfbFieldTypes(name) {
118 case pb.OxmOfbFieldTypes_OFPXMT_OFB_IN_PORT:
119 port := val.(ofp.Port)
120 var value pb.OfpOxmOfbField_Port
121 value.Port = uint32(port)
122 field.Value = &value
123 case pb.OxmOfbFieldTypes_OFPXMT_OFB_IN_PHY_PORT:
124 phyPort := val.(uint32)
125 var value pb.OfpOxmOfbField_PhysicalPort
126 value.PhysicalPort = phyPort
127 field.Value = &value
128 case pb.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
129 metadata := val.(uint64)
130 var value pb.OfpOxmOfbField_TableMetadata
131 value.TableMetadata = metadata
132 field.Value = &value
133 case pb.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
134 ethType := val.(ofp.EthernetType)
135 var value pb.OfpOxmOfbField_EthType
136 value.EthType = uint32(ethType)
137 field.Value = &value
138 case pb.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
139 proto := val.(ofp.IpPrototype)
140 var value pb.OfpOxmOfbField_IpProto
141 value.IpProto = uint32(proto)
142 field.Value = &value
143 case pb.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
144 udpSrc := val.(uint16)
145 var value pb.OfpOxmOfbField_UdpSrc
146 value.UdpSrc = uint32(udpSrc)
147 log.Printf("udpSrc %v", udpSrc)
148 field.Value = &value
149 case pb.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
150 udpDst := val.(uint16)
151 var value pb.OfpOxmOfbField_UdpDst
152 value.UdpDst = uint32(udpDst)
153 field.Value = &value
Don Newtone0d34a82019-11-14 10:58:06 -0500154 case pb.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
Don Newtonb437c6f2019-12-18 11:51:57 -0500155 vid := (val.(uint16) & 0xfff) | 0x1000
Don Newtone0d34a82019-11-14 10:58:06 -0500156 var value pb.OfpOxmOfbField_VlanVid
157 value.VlanVid = uint32(vid)
158 field.Value = &value
Don Newton98fd8812019-09-23 15:15:02 -0400159 }
160 oxmList = append(oxmList, &ofpOxmField)
161 }
162 flowMatch.OxmFields = oxmList
163 flowMod.Match = &flowMatch
164 var instructions []*pb.OfpInstruction
165 ofpInstructions := flowAdd.GetInstructions()
166 for i := 0; i < len(ofpInstructions); i++ {
167 var instruction pb.OfpInstruction
168 ofpInstruction := ofpInstructions[i]
169 instructionType := ofpInstruction.GetType()
170 instruction.Type = uint32(instructionType)
171 switch instructionType {
Don Newtone0d34a82019-11-14 10:58:06 -0500172 case ofp.OFPITGotoTable:
Don Newton98fd8812019-09-23 15:15:02 -0400173 goToTable := ofpInstruction.(ofp.IInstructionGotoTable)
174 var ofpGoToTable openflow_13.OfpInstruction_GotoTable
Don Newtone0d34a82019-11-14 10:58:06 -0500175 var oGoToTable openflow_13.OfpInstructionGotoTable
176 ofpGoToTable.GotoTable = &oGoToTable
Don Newton98fd8812019-09-23 15:15:02 -0400177 ofpGoToTable.GotoTable.TableId = uint32(goToTable.GetTableId())
178 instruction.Data = &ofpGoToTable
Don Newtone0d34a82019-11-14 10:58:06 -0500179 case ofp.OFPITWriteMetadata:
Don Newton98fd8812019-09-23 15:15:02 -0400180 writeMetaData := ofpInstruction.(ofp.IInstructionWriteMetadata)
181 var ofpWriteMetadata openflow_13.OfpInstruction_WriteMetadata
Don Newtone0d34a82019-11-14 10:58:06 -0500182 var writeMetadata openflow_13.OfpInstructionWriteMetadata
183 ofpWriteMetadata.WriteMetadata = &writeMetadata
Don Newton98fd8812019-09-23 15:15:02 -0400184 ofpWriteMetadata.WriteMetadata.Metadata = writeMetaData.GetMetadata()
185 ofpWriteMetadata.WriteMetadata.MetadataMask = writeMetaData.GetMetadataMask()
186 instruction.Data = &ofpWriteMetadata
Don Newtone0d34a82019-11-14 10:58:06 -0500187 case ofp.OFPITWriteActions:
Don Newton98fd8812019-09-23 15:15:02 -0400188 writeAction := ofpInstruction.(ofp.IInstructionWriteActions)
189 var ofpInstructionActions openflow_13.OfpInstruction_Actions
190 var ofpActions []*openflow_13.OfpAction
191 actions := writeAction.GetActions()
192 for i := 0; i < len(actions); i++ {
193 action := actions[i]
194 ofpAction := extractAction(action)
195 ofpActions = append(ofpActions, ofpAction)
196 }
197 instruction.Data = &ofpInstructionActions
Don Newtone0d34a82019-11-14 10:58:06 -0500198 case ofp.OFPITApplyActions:
Don Newton98fd8812019-09-23 15:15:02 -0400199 applyAction := ofpInstruction.(ofp.IInstructionApplyActions)
200 var ofpInstructionActions openflow_13.OfpInstruction_Actions
201 var ofpActions []*openflow_13.OfpAction
202 actions := applyAction.GetActions()
203 for i := 0; i < len(actions); i++ {
204 action := actions[i]
205 ofpAction := extractAction(action)
206 ofpActions = append(ofpActions, ofpAction)
207 }
208 var actionsHolder openflow_13.OfpInstructionActions
209 actionsHolder.Actions = ofpActions
210 ofpInstructionActions.Actions = &actionsHolder
211 instruction.Data = &ofpInstructionActions
Don Newtone0d34a82019-11-14 10:58:06 -0500212 case ofp.OFPITMeter:
213 var instructionMeter = ofpInstruction.(ofp.IInstructionMeter)
214 var meterInstruction openflow_13.OfpInstruction_Meter
215 var meter openflow_13.OfpInstructionMeter
Don Newton98fd8812019-09-23 15:15:02 -0400216
Don Newtone0d34a82019-11-14 10:58:06 -0500217 meter.MeterId = instructionMeter.GetMeterId()
218 meterInstruction.Meter = &meter
219 instruction.Data = &meterInstruction
Don Newton98fd8812019-09-23 15:15:02 -0400220 }
221 instructions = append(instructions, &instruction)
222 }
223
224 flowMod.Instructions = instructions
225 flowUpdate.FlowMod = &flowMod
226 grpcClient := *getGrpcClient()
227 flowUpdateJs, _ := json.Marshal(flowUpdate)
228 log.Printf("FLOW UPDATE %s", flowUpdateJs)
229 empty, err := grpcClient.UpdateLogicalDeviceFlowTable(context.Background(), &flowUpdate)
230 if err != nil {
231 log.Printf("ERROR DOING FLOW MOD ADD %v", err)
232 }
233 emptyJs, _ := json.Marshal(empty)
234 log.Printf("FLOW MOD RESPONSE %s", emptyJs)
235
236}
237
238func handleFlowMod(flowMod *ofp.FlowMod, deviceId string) {
239 js, _ := json.Marshal(flowMod)
240 log.Printf("handleFlowMod called with %s", js)
241}
242
243func handleFlowModStrict(flowModStrict *ofp.FlowModifyStrict, deviceId string) {
244 js, _ := json.Marshal(flowModStrict)
245 log.Printf("handleFlowModStrict called with %s", js)
246}
247func handleFlowDelete(flowDelete *ofp.FlowDelete, deviceId string) {
248 js, _ := json.Marshal(flowDelete)
249 log.Printf("handleFlowDelete called with %s", js)
250
251}
252func handleFlowDeleteStrict(flowDeleteStrict *ofp.FlowDeleteStrict, deviceId string) {
253 js, _ := json.Marshal(flowDeleteStrict)
254 log.Printf("handleFlowDeleteStrict called with %s", js)
255
Don Newtonb437c6f2019-12-18 11:51:57 -0500256 var flowUpdate openflow_13.FlowTableUpdate
257 flowUpdate.Id = deviceId
258 var flowMod pb.OfpFlowMod
259 flowMod.Cookie = flowDeleteStrict.Cookie
260 flowMod.CookieMask = flowDeleteStrict.CookieMask
261 flowMod.TableId = uint32(flowDeleteStrict.TableId)
262 flowMod.Command = pb.OfpFlowModCommand_OFPFC_DELETE_STRICT
263 flowMod.IdleTimeout = uint32(flowDeleteStrict.IdleTimeout)
264 flowMod.HardTimeout = uint32(flowDeleteStrict.HardTimeout)
265 flowMod.Priority = uint32(flowDeleteStrict.Priority)
266 flowMod.BufferId = flowDeleteStrict.BufferId
267 flowMod.OutPort = uint32(flowDeleteStrict.OutPort)
268 flowMod.OutGroup = uint32(flowDeleteStrict.OutGroup)
269 flowMod.Flags = uint32(flowDeleteStrict.Flags)
270 inMatch := flowDeleteStrict.Match
271 var flowMatch pb.OfpMatch
272 flowMatch.Type = pb.OfpMatchType(inMatch.GetType())
273 var oxmList []*pb.OfpOxmField
274 inOxmList := inMatch.GetOxmList()
275 for i := 0; i < len(inOxmList); i++ {
276 oxmField := inOxmList[i]
277 j, _ := json.Marshal(oxmField)
278
279 name := oxmMap[oxmField.GetOXMName()]
280 log.Printf("\n\n\n %s %d %s\n\n\n", j, name, oxmField.GetOXMName())
281
282 val := oxmField.GetOXMValue()
283 var ofpOxmField pb.OfpOxmField
284 ofpOxmField.OxmClass = ofp.OFPXMCOpenflowBasic
285 var field pb.OfpOxmOfbField
286
287 field.Type = pb.OxmOfbFieldTypes(name)
288 log.Println("****\nFieldType: " + openflow_13.OxmOfbFieldTypes_name[name] + "\n\n\n\n")
289
290 var x openflow_13.OfpOxmField_OfbField
291 x.OfbField = &field
292 ofpOxmField.Field = &x
293
294 switch pb.OxmOfbFieldTypes(name) {
295 case pb.OxmOfbFieldTypes_OFPXMT_OFB_IN_PORT:
296 port := val.(ofp.Port)
297 var value pb.OfpOxmOfbField_Port
298 value.Port = uint32(port)
299 field.Value = &value
300 case pb.OxmOfbFieldTypes_OFPXMT_OFB_IN_PHY_PORT:
301 phyPort := val.(uint32)
302 var value pb.OfpOxmOfbField_PhysicalPort
303 value.PhysicalPort = phyPort
304 field.Value = &value
305 case pb.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
306 metadata := val.(uint64)
307 var value pb.OfpOxmOfbField_TableMetadata
308 value.TableMetadata = metadata
309 field.Value = &value
310 case pb.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
311 ethType := val.(ofp.EthernetType)
312 var value pb.OfpOxmOfbField_EthType
313 value.EthType = uint32(ethType)
314 field.Value = &value
315 case pb.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
316 proto := val.(ofp.IpPrototype)
317 var value pb.OfpOxmOfbField_IpProto
318 value.IpProto = uint32(proto)
319 field.Value = &value
320 case pb.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
321 udpSrc := val.(uint16)
322 var value pb.OfpOxmOfbField_UdpSrc
323 value.UdpSrc = uint32(udpSrc)
324 log.Printf("udpSrc %v", udpSrc)
325 field.Value = &value
326 case pb.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
327 udpDst := val.(uint16)
328 var value pb.OfpOxmOfbField_UdpDst
329 value.UdpDst = uint32(udpDst)
330 field.Value = &value
331 case pb.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
332 //vid := (val.(uint16) & 0xfff)|0x1000
333 vid := val.(uint16)
334 //vid := val.(uint16) & 0xfff
335 var value pb.OfpOxmOfbField_VlanVid
336 value.VlanVid = uint32(vid)
337 field.Value = &value
338 }
339 oxmList = append(oxmList, &ofpOxmField)
340 }
341 flowMatch.OxmFields = oxmList
342 flowMod.Match = &flowMatch
343 /*var instructions []*pb.OfpInstruction
344 ofpInstructions := flowDeleteStrict.GetInstructions()
345 for i := 0; i < len(ofpInstructions); i++ {
346 var instruction pb.OfpInstruction
347 ofpInstruction := ofpInstructions[i]
348 instructionType := ofpInstruction.GetType()
349 instruction.Type = uint32(instructionType)
350 switch instructionType {
351 case ofp.OFPITGotoTable:
352 goToTable := ofpInstruction.(ofp.IInstructionGotoTable)
353 var ofpGoToTable openflow_13.OfpInstruction_GotoTable
354 var oGoToTable openflow_13.OfpInstructionGotoTable
355 ofpGoToTable.GotoTable = &oGoToTable
356 ofpGoToTable.GotoTable.TableId = uint32(goToTable.GetTableId())
357 instruction.Data = &ofpGoToTable
358 case ofp.OFPITWriteMetadata:
359 writeMetaData := ofpInstruction.(ofp.IInstructionWriteMetadata)
360 var ofpWriteMetadata openflow_13.OfpInstruction_WriteMetadata
361 var writeMetadata openflow_13.OfpInstructionWriteMetadata
362 ofpWriteMetadata.WriteMetadata = &writeMetadata
363 ofpWriteMetadata.WriteMetadata.Metadata = writeMetaData.GetMetadata()
364 ofpWriteMetadata.WriteMetadata.MetadataMask = writeMetaData.GetMetadataMask()
365 instruction.Data = &ofpWriteMetadata
366 case ofp.OFPITWriteActions:
367 writeAction := ofpInstruction.(ofp.IInstructionWriteActions)
368 var ofpInstructionActions openflow_13.OfpInstruction_Actions
369 var ofpActions []*openflow_13.OfpAction
370 actions := writeAction.GetActions()
371 for i := 0; i < len(actions); i++ {
372 action := actions[i]
373 ofpAction := extractAction(action)
374 ofpActions = append(ofpActions, ofpAction)
375 }
376 instruction.Data = &ofpInstructionActions
377 case ofp.OFPITApplyActions:
378 applyAction := ofpInstruction.(ofp.IInstructionApplyActions)
379 var ofpInstructionActions openflow_13.OfpInstruction_Actions
380 var ofpActions []*openflow_13.OfpAction
381 actions := applyAction.GetActions()
382 for i := 0; i < len(actions); i++ {
383 action := actions[i]
384 ofpAction := extractAction(action)
385 ofpActions = append(ofpActions, ofpAction)
386 }
387 var actionsHolder openflow_13.OfpInstructionActions
388 actionsHolder.Actions = ofpActions
389 ofpInstructionActions.Actions = &actionsHolder
390 instruction.Data = &ofpInstructionActions
391 case ofp.OFPITMeter:
392 var instructionMeter = ofpInstruction.(ofp.IInstructionMeter)
393 var meterInstruction openflow_13.OfpInstruction_Meter
394 var meter openflow_13.OfpInstructionMeter
395
396 meter.MeterId = instructionMeter.GetMeterId()
397 meterInstruction.Meter = &meter
398 instruction.Data = &meterInstruction
399 }
400 instructions = append(instructions, &instruction)
401 }
402
403 flowMod.Instructions = instructions
404
405 */
406 flowUpdate.FlowMod = &flowMod
407 grpcClient := *getGrpcClient()
408 flowUpdateJs, _ := json.Marshal(flowUpdate)
409 log.Printf("FLOW UPDATE %s", flowUpdateJs)
410 empty, err := grpcClient.UpdateLogicalDeviceFlowTable(context.Background(), &flowUpdate)
411 if err != nil {
412 log.Printf("ERROR DOING FLOW MOD ADD %v", err)
413 }
414 emptyJs, _ := json.Marshal(empty)
415 log.Printf("FLOW MOD RESPONSE %s", emptyJs)
416
Don Newton98fd8812019-09-23 15:15:02 -0400417}