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