blob: 706e9a7ae4a9cdc01673797b3030d3ccdb5de034 [file] [log] [blame]
Don Newtone0d34a82019-11-14 10:58:06 -05001/*
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*/
16package openflow
17
18import (
19 "encoding/json"
20 "github.com/donNewtonAlpha/goloxi"
21 ofp "github.com/donNewtonAlpha/goloxi/of13"
22 "github.com/opencord/voltha-protos/go/openflow_13"
23 pb "github.com/opencord/voltha-protos/go/voltha"
24 "log"
25 "unsafe"
26)
27
28func parseOxm(ofbField *openflow_13.OfpOxmOfbField) (goloxi.IOxm, uint16) {
29 switch ofbField.Type {
30 case pb.OxmOfbFieldTypes_OFPXMT_OFB_IN_PORT:
31 ofpInPort := ofp.NewOxmInPort()
32 val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_Port)
33 ofpInPort.Value = ofp.Port(val.Port)
34 return ofpInPort, 4
35 case pb.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
36 ofpEthType := ofp.NewOxmEthType()
37 val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_EthType)
38 ofpEthType.Value = ofp.EthernetType(val.EthType)
39 return ofpEthType, 2
40 case pb.OxmOfbFieldTypes_OFPXMT_OFB_IN_PHY_PORT:
41 ofpInPhyPort := ofp.NewOxmInPhyPort()
42 val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_PhysicalPort)
43 ofpInPhyPort.Value = ofp.Port(val.PhysicalPort)
44 return ofpInPhyPort, 4
45 case pb.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
46 ofpIpProto := ofp.NewOxmIpProto()
47 val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_IpProto)
48 ofpIpProto.Value = ofp.IpPrototype(val.IpProto)
49 return ofpIpProto, 1
50 case pb.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
51 ofpUdpSrc := ofp.NewOxmUdpSrc()
52 val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_UdpSrc)
53 ofpUdpSrc.Value = uint16(val.UdpSrc)
54 return ofpUdpSrc, 2
55 case pb.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
56 ofpUdpDst := ofp.NewOxmUdpDst()
57 val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_UdpDst)
58 ofpUdpDst.Value = uint16(val.UdpDst)
59 return ofpUdpDst, 2
60 case pb.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
61 ofpVlanVid := ofp.NewOxmVlanVid()
62 val := ofbField.GetValue()
63 if val != nil {
64 vlanId := val.(*openflow_13.OfpOxmOfbField_VlanVid)
65 ofpVlanVid.Value = uint16(vlanId.VlanVid) + 0x1000
66 } else {
67 ofpVlanVid.Value = uint16(0)
68 }
69 return ofpVlanVid, 2
70 case pb.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
71 ofpMetadata := ofp.NewOxmMetadata()
72 val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_TableMetadata)
73 ofpMetadata.Value = val.TableMetadata
74 return ofpMetadata, 8
75 default:
76 log.Printf("handleFlowStatsRequest Unhandled OxmField %v", ofbField.Type)
77 }
78 return nil, 0
79}
80func parseInstructions(ofpInstruction *openflow_13.OfpInstruction) (ofp.IInstruction, uint16) {
81 instType := ofpInstruction.Type
82 data := ofpInstruction.GetData()
83 switch instType {
84 case ofp.OFPITWriteMetadata:
85 instruction := ofp.NewInstructionWriteMetadata()
86 instruction.Len = 24
87 metadata := data.(*openflow_13.OfpInstruction_WriteMetadata).WriteMetadata
88 instruction.Metadata = uint64(metadata.Metadata)
89 return instruction, 24
90 case ofp.OFPITMeter:
91 instruction := ofp.NewInstructionMeter()
92 instruction.Len = 8
93 meter := data.(*openflow_13.OfpInstruction_Meter).Meter
94 instruction.MeterId = meter.MeterId
95 return instruction, 8
96 case ofp.OFPITGotoTable:
97 instruction := ofp.NewInstructionGotoTable()
98 instruction.Len = 8
99 gotoTable := data.(*openflow_13.OfpInstruction_GotoTable).GotoTable
100 instruction.TableId = uint8(gotoTable.TableId)
101 return instruction, 8
102 case ofp.OFPITApplyActions:
103 instruction := ofp.NewInstructionApplyActions()
104 var instructionSize uint16
105 instructionSize = 8
106 ofpActions := ofpInstruction.GetActions().Actions
107 var actions []goloxi.IAction
108 for i := 0; i < len(ofpActions); i++ {
109 ofpAction := ofpActions[i]
110 action, actionSize := parseAction(ofpAction)
111 js, _ := json.Marshal(action)
112 log.Printf("ACTION size(%d) value %s", actionSize, js)
113 actions = append(actions, action)
114 instructionSize += actionSize
115 mySize := unsafe.Sizeof(*instruction)
116 log.Printf("Calculated Size %d Measured size %d", instructionSize, mySize)
117
118 }
119 instruction.Actions = actions
120 instruction.SetLen(instructionSize)
121 js, _ := json.Marshal(instruction)
122 log.Printf("INSTRUCTION %s", js)
123 return instruction, instructionSize
124 }
125 //shouldn't have reached here :<
126 js, _ := json.Marshal(ofpInstruction)
127 log.Printf("Parse Instruction Failed ofpInstruction : %s", js)
128 return nil, 0
129}
130func parseAction(ofpAction *openflow_13.OfpAction) (goloxi.IAction, uint16) {
131 js, _ := json.Marshal(ofpAction)
132 log.Printf("ACTION BEFORE %s", js)
133 switch ofpAction.Type {
134 case openflow_13.OfpActionType_OFPAT_OUTPUT:
135 ofpOutputAction := ofpAction.GetOutput()
136 outputAction := ofp.NewActionOutput()
137 outputAction.Port = ofp.Port(ofpOutputAction.Port)
138 outputAction.MaxLen = uint16(ofpOutputAction.MaxLen)
139 outputAction.Len = 16
140 return outputAction, 16
141 case openflow_13.OfpActionType_OFPAT_PUSH_VLAN:
142 ofpPushVlanAction := ofp.NewActionPushVlan()
143 ofpPushVlanAction.Ethertype = uint16(ofpAction.GetPush().Ethertype)
144 ofpPushVlanAction.Len = 8
145 return ofpPushVlanAction, 8
146 case openflow_13.OfpActionType_OFPAT_POP_VLAN:
147 ofpPopVlanAction := ofp.NewActionPopVlan()
148 ofpPopVlanAction.Len = 8
149 return ofpPopVlanAction, 8
150 case openflow_13.OfpActionType_OFPAT_SET_FIELD:
151 ofpActionSetField := ofpAction.GetSetField()
152 setFieldAction := ofp.NewActionSetField()
153
154 iOxm, _ := parseOxm(ofpActionSetField.GetField().GetOfbField())
155 setFieldAction.Field = iOxm
156 setFieldAction.Len = 10
157 return setFieldAction, 10
158 default:
159 js, _ := json.Marshal(ofpAction)
160 log.Printf("UNKNOWN ACTION %s", js)
161 }
162 return nil, 0
163}
164func parsePortStats(port *pb.LogicalPort) ofp.PortStatsEntry {
165 stats := port.OfpPortStats
166 port.OfpPort.GetPortNo()
167 var entry ofp.PortStatsEntry
168 entry.SetPortNo(ofp.Port(port.OfpPort.GetPortNo()))
169 entry.SetRxPackets(stats.GetRxPackets())
170 entry.SetTxPackets(stats.GetTxPackets())
171 entry.SetRxBytes(stats.GetRxBytes())
172 entry.SetTxBytes(stats.GetTxBytes())
173 entry.SetRxDropped(stats.GetRxDropped())
174 entry.SetTxDropped(stats.GetTxDropped())
175 entry.SetRxErrors(stats.GetRxErrors())
176 entry.SetTxErrors(stats.GetTxErrors())
177 entry.SetRxFrameErr(stats.GetRxFrameErr())
178 entry.SetRxOverErr(stats.GetRxOverErr())
179 entry.SetRxCrcErr(stats.GetRxCrcErr())
180 entry.SetCollisions(stats.GetCollisions())
181 entry.SetDurationSec(stats.GetDurationSec())
182 entry.SetDurationNsec(stats.GetDurationNsec())
183 return entry
184}