blob: f4177d1c205d73dfe6dab31041a585943f918446 [file] [log] [blame]
Don Newtone0d34a82019-11-14 10:58:06 -05001/*
David K. Bainbridge157bdab2020-01-16 14:38:05 -08002 Copyright 2020 the original author or authors.
Don Newtone0d34a82019-11-14 10:58:06 -05003
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 Newtonb437c6f2019-12-18 11:51:57 -050020 "github.com/donNewtonAlpha/goloxi"
21 ofp "github.com/donNewtonAlpha/goloxi/of13"
David K. Bainbridge157bdab2020-01-16 14:38:05 -080022 "github.com/opencord/voltha-lib-go/v2/pkg/log"
Don Newtonb437c6f2019-12-18 11:51:57 -050023 "github.com/opencord/voltha-protos/v2/go/openflow_13"
David K. Bainbridge157bdab2020-01-16 14:38:05 -080024 "github.com/opencord/voltha-protos/v2/go/voltha"
Don Newtone0d34a82019-11-14 10:58:06 -050025)
26
Don Newton7577f072020-01-06 12:41:11 -050027func parseOxm(ofbField *openflow_13.OfpOxmOfbField, DeviceID string) (goloxi.IOxm, uint16) {
David K. Bainbridge157bdab2020-01-16 14:38:05 -080028 if logger.V(log.DebugLevel) {
Don Newton7577f072020-01-06 12:41:11 -050029 js, _ := json.Marshal(ofbField)
David K. Bainbridge157bdab2020-01-16 14:38:05 -080030 logger.Debugw("parseOxm called",
31 log.Fields{
32 "device-id": DeviceID,
33 "ofbField": js})
Don Newton7577f072020-01-06 12:41:11 -050034 }
35
Don Newtone0d34a82019-11-14 10:58:06 -050036 switch ofbField.Type {
David K. Bainbridge157bdab2020-01-16 14:38:05 -080037 case voltha.OxmOfbFieldTypes_OFPXMT_OFB_IN_PORT:
Don Newtone0d34a82019-11-14 10:58:06 -050038 ofpInPort := ofp.NewOxmInPort()
39 val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_Port)
40 ofpInPort.Value = ofp.Port(val.Port)
41 return ofpInPort, 4
David K. Bainbridge157bdab2020-01-16 14:38:05 -080042 case voltha.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
Don Newtone0d34a82019-11-14 10:58:06 -050043 ofpEthType := ofp.NewOxmEthType()
44 val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_EthType)
45 ofpEthType.Value = ofp.EthernetType(val.EthType)
46 return ofpEthType, 2
David K. Bainbridge157bdab2020-01-16 14:38:05 -080047 case voltha.OxmOfbFieldTypes_OFPXMT_OFB_IN_PHY_PORT:
Don Newtone0d34a82019-11-14 10:58:06 -050048 ofpInPhyPort := ofp.NewOxmInPhyPort()
49 val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_PhysicalPort)
50 ofpInPhyPort.Value = ofp.Port(val.PhysicalPort)
51 return ofpInPhyPort, 4
David K. Bainbridge157bdab2020-01-16 14:38:05 -080052 case voltha.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
Don Newtone0d34a82019-11-14 10:58:06 -050053 ofpIpProto := ofp.NewOxmIpProto()
54 val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_IpProto)
55 ofpIpProto.Value = ofp.IpPrototype(val.IpProto)
56 return ofpIpProto, 1
David K. Bainbridge157bdab2020-01-16 14:38:05 -080057 case voltha.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
Don Newtone0d34a82019-11-14 10:58:06 -050058 ofpUdpSrc := ofp.NewOxmUdpSrc()
59 val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_UdpSrc)
60 ofpUdpSrc.Value = uint16(val.UdpSrc)
61 return ofpUdpSrc, 2
David K. Bainbridge157bdab2020-01-16 14:38:05 -080062 case voltha.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
Don Newtone0d34a82019-11-14 10:58:06 -050063 ofpUdpDst := ofp.NewOxmUdpDst()
64 val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_UdpDst)
65 ofpUdpDst.Value = uint16(val.UdpDst)
66 return ofpUdpDst, 2
David K. Bainbridge157bdab2020-01-16 14:38:05 -080067 case voltha.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
Don Newtone0d34a82019-11-14 10:58:06 -050068 ofpVlanVid := ofp.NewOxmVlanVid()
69 val := ofbField.GetValue()
70 if val != nil {
71 vlanId := val.(*openflow_13.OfpOxmOfbField_VlanVid)
Don Newtonb437c6f2019-12-18 11:51:57 -050072 ofpVlanVid.Value = uint16(vlanId.VlanVid) | 0x1000
Don Newtone0d34a82019-11-14 10:58:06 -050073 } else {
74 ofpVlanVid.Value = uint16(0)
75 }
76 return ofpVlanVid, 2
David K. Bainbridge157bdab2020-01-16 14:38:05 -080077 case voltha.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
Don Newtone0d34a82019-11-14 10:58:06 -050078 ofpMetadata := ofp.NewOxmMetadata()
79 val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_TableMetadata)
80 ofpMetadata.Value = val.TableMetadata
81 return ofpMetadata, 8
82 default:
David K. Bainbridge157bdab2020-01-16 14:38:05 -080083 if logger.V(log.WarnLevel) {
84 js, _ := json.Marshal(ofbField)
85 logger.Warnw("ParseOXM Unhandled OxmField",
86 log.Fields{
87 "device-id": DeviceID,
88 "OfbField": js})
89 }
Don Newtone0d34a82019-11-14 10:58:06 -050090 }
91 return nil, 0
92}
David K. Bainbridge157bdab2020-01-16 14:38:05 -080093
Don Newton7577f072020-01-06 12:41:11 -050094func parseInstructions(ofpInstruction *openflow_13.OfpInstruction, DeviceID string) (ofp.IInstruction, uint16) {
David K. Bainbridge157bdab2020-01-16 14:38:05 -080095 if logger.V(log.DebugLevel) {
Don Newton7577f072020-01-06 12:41:11 -050096 js, _ := json.Marshal(ofpInstruction)
David K. Bainbridge157bdab2020-01-16 14:38:05 -080097 logger.Debugw("parseInstructions called",
98 log.Fields{
99 "device-id": DeviceID,
100 "Instruction": js})
Don Newton7577f072020-01-06 12:41:11 -0500101 }
Don Newtone0d34a82019-11-14 10:58:06 -0500102 instType := ofpInstruction.Type
103 data := ofpInstruction.GetData()
104 switch instType {
105 case ofp.OFPITWriteMetadata:
106 instruction := ofp.NewInstructionWriteMetadata()
107 instruction.Len = 24
108 metadata := data.(*openflow_13.OfpInstruction_WriteMetadata).WriteMetadata
109 instruction.Metadata = uint64(metadata.Metadata)
110 return instruction, 24
111 case ofp.OFPITMeter:
112 instruction := ofp.NewInstructionMeter()
113 instruction.Len = 8
114 meter := data.(*openflow_13.OfpInstruction_Meter).Meter
115 instruction.MeterId = meter.MeterId
116 return instruction, 8
117 case ofp.OFPITGotoTable:
118 instruction := ofp.NewInstructionGotoTable()
119 instruction.Len = 8
120 gotoTable := data.(*openflow_13.OfpInstruction_GotoTable).GotoTable
121 instruction.TableId = uint8(gotoTable.TableId)
122 return instruction, 8
123 case ofp.OFPITApplyActions:
124 instruction := ofp.NewInstructionApplyActions()
125 var instructionSize uint16
126 instructionSize = 8
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800127 //ofpActions := ofpInstruction.GetActions().Actions
Don Newtone0d34a82019-11-14 10:58:06 -0500128 var actions []goloxi.IAction
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800129 for _, ofpAction := range ofpInstruction.GetActions().Actions {
Don Newton7577f072020-01-06 12:41:11 -0500130 action, actionSize := parseAction(ofpAction, DeviceID)
Don Newtone0d34a82019-11-14 10:58:06 -0500131 actions = append(actions, action)
132 instructionSize += actionSize
Don Newtone0d34a82019-11-14 10:58:06 -0500133
134 }
135 instruction.Actions = actions
136 instruction.SetLen(instructionSize)
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800137 if logger.V(log.DebugLevel) {
Don Newton7577f072020-01-06 12:41:11 -0500138 js, _ := json.Marshal(instruction)
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800139 logger.Debugw("parseInstructions returning",
140 log.Fields{
141 "device-id": DeviceID,
142 "size": instructionSize,
143 "parsed-instruction": js})
Don Newton7577f072020-01-06 12:41:11 -0500144 }
Don Newtone0d34a82019-11-14 10:58:06 -0500145 return instruction, instructionSize
146 }
147 //shouldn't have reached here :<
Don Newtone0d34a82019-11-14 10:58:06 -0500148 return nil, 0
149}
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800150
Don Newton7577f072020-01-06 12:41:11 -0500151func parseAction(ofpAction *openflow_13.OfpAction, DeviceID string) (goloxi.IAction, uint16) {
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800152 if logger.V(log.DebugLevel) {
Don Newton7577f072020-01-06 12:41:11 -0500153 js, _ := json.Marshal(ofpAction)
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800154 logger.Debugw("parseAction called",
155 log.Fields{
156 "device-id": DeviceID,
157 "action": js})
Don Newton7577f072020-01-06 12:41:11 -0500158 }
Don Newtone0d34a82019-11-14 10:58:06 -0500159 switch ofpAction.Type {
160 case openflow_13.OfpActionType_OFPAT_OUTPUT:
161 ofpOutputAction := ofpAction.GetOutput()
162 outputAction := ofp.NewActionOutput()
163 outputAction.Port = ofp.Port(ofpOutputAction.Port)
164 outputAction.MaxLen = uint16(ofpOutputAction.MaxLen)
165 outputAction.Len = 16
166 return outputAction, 16
167 case openflow_13.OfpActionType_OFPAT_PUSH_VLAN:
168 ofpPushVlanAction := ofp.NewActionPushVlan()
169 ofpPushVlanAction.Ethertype = uint16(ofpAction.GetPush().Ethertype)
170 ofpPushVlanAction.Len = 8
171 return ofpPushVlanAction, 8
172 case openflow_13.OfpActionType_OFPAT_POP_VLAN:
173 ofpPopVlanAction := ofp.NewActionPopVlan()
174 ofpPopVlanAction.Len = 8
175 return ofpPopVlanAction, 8
176 case openflow_13.OfpActionType_OFPAT_SET_FIELD:
177 ofpActionSetField := ofpAction.GetSetField()
178 setFieldAction := ofp.NewActionSetField()
179
Don Newton7577f072020-01-06 12:41:11 -0500180 iOxm, _ := parseOxm(ofpActionSetField.GetField().GetOfbField(), DeviceID)
Don Newtone0d34a82019-11-14 10:58:06 -0500181 setFieldAction.Field = iOxm
Don Newtonb437c6f2019-12-18 11:51:57 -0500182 setFieldAction.Len = 16
183 return setFieldAction, 16
Don Newtone0d34a82019-11-14 10:58:06 -0500184 default:
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800185 if logger.V(log.WarnLevel) {
186 js, _ := json.Marshal(ofpAction)
187 logger.Warnw("parseAction unknow action",
188 log.Fields{
189 "device-id": DeviceID,
190 "action": js})
191 }
Don Newtone0d34a82019-11-14 10:58:06 -0500192 }
193 return nil, 0
194}
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800195
196func parsePortStats(port *voltha.LogicalPort) *ofp.PortStatsEntry {
Don Newtone0d34a82019-11-14 10:58:06 -0500197 stats := port.OfpPortStats
198 port.OfpPort.GetPortNo()
199 var entry ofp.PortStatsEntry
200 entry.SetPortNo(ofp.Port(port.OfpPort.GetPortNo()))
201 entry.SetRxPackets(stats.GetRxPackets())
202 entry.SetTxPackets(stats.GetTxPackets())
203 entry.SetRxBytes(stats.GetRxBytes())
204 entry.SetTxBytes(stats.GetTxBytes())
205 entry.SetRxDropped(stats.GetRxDropped())
206 entry.SetTxDropped(stats.GetTxDropped())
207 entry.SetRxErrors(stats.GetRxErrors())
208 entry.SetTxErrors(stats.GetTxErrors())
209 entry.SetRxFrameErr(stats.GetRxFrameErr())
210 entry.SetRxOverErr(stats.GetRxOverErr())
211 entry.SetRxCrcErr(stats.GetRxCrcErr())
212 entry.SetCollisions(stats.GetCollisions())
213 entry.SetDurationSec(stats.GetDurationSec())
214 entry.SetDurationNsec(stats.GetDurationNsec())
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800215 return &entry
Don Newtone0d34a82019-11-14 10:58:06 -0500216}