blob: 30ec6726080a5447d857fe9504aebaee74fc1338 [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 Newtonb437c6f2019-12-18 11:51:57 -050020
21 "github.com/donNewtonAlpha/goloxi"
22 ofp "github.com/donNewtonAlpha/goloxi/of13"
Don Newton7577f072020-01-06 12:41:11 -050023 "github.com/opencord/ofagent-go/settings"
24 l "github.com/opencord/voltha-lib-go/v2/pkg/log"
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 Newtone0d34a82019-11-14 10:58:06 -050027)
28
Don Newton7577f072020-01-06 12:41:11 -050029func parseOxm(ofbField *openflow_13.OfpOxmOfbField, DeviceID string) (goloxi.IOxm, uint16) {
30 if settings.GetDebug(DeviceID) {
31 js, _ := json.Marshal(ofbField)
32 logger.Debugw("parseOxm called", l.Fields{"DeviceID": DeviceID, "ofbField": js})
33 }
34
Don Newtone0d34a82019-11-14 10:58:06 -050035 switch ofbField.Type {
36 case pb.OxmOfbFieldTypes_OFPXMT_OFB_IN_PORT:
37 ofpInPort := ofp.NewOxmInPort()
38 val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_Port)
39 ofpInPort.Value = ofp.Port(val.Port)
40 return ofpInPort, 4
41 case pb.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
42 ofpEthType := ofp.NewOxmEthType()
43 val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_EthType)
44 ofpEthType.Value = ofp.EthernetType(val.EthType)
45 return ofpEthType, 2
46 case pb.OxmOfbFieldTypes_OFPXMT_OFB_IN_PHY_PORT:
47 ofpInPhyPort := ofp.NewOxmInPhyPort()
48 val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_PhysicalPort)
49 ofpInPhyPort.Value = ofp.Port(val.PhysicalPort)
50 return ofpInPhyPort, 4
51 case pb.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
52 ofpIpProto := ofp.NewOxmIpProto()
53 val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_IpProto)
54 ofpIpProto.Value = ofp.IpPrototype(val.IpProto)
55 return ofpIpProto, 1
56 case pb.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
57 ofpUdpSrc := ofp.NewOxmUdpSrc()
58 val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_UdpSrc)
59 ofpUdpSrc.Value = uint16(val.UdpSrc)
60 return ofpUdpSrc, 2
61 case pb.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
62 ofpUdpDst := ofp.NewOxmUdpDst()
63 val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_UdpDst)
64 ofpUdpDst.Value = uint16(val.UdpDst)
65 return ofpUdpDst, 2
66 case pb.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
67 ofpVlanVid := ofp.NewOxmVlanVid()
68 val := ofbField.GetValue()
69 if val != nil {
70 vlanId := val.(*openflow_13.OfpOxmOfbField_VlanVid)
Don Newtonb437c6f2019-12-18 11:51:57 -050071 ofpVlanVid.Value = uint16(vlanId.VlanVid) | 0x1000
Don Newtone0d34a82019-11-14 10:58:06 -050072 } else {
73 ofpVlanVid.Value = uint16(0)
74 }
75 return ofpVlanVid, 2
76 case pb.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
77 ofpMetadata := ofp.NewOxmMetadata()
78 val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_TableMetadata)
79 ofpMetadata.Value = val.TableMetadata
80 return ofpMetadata, 8
81 default:
Don Newton7577f072020-01-06 12:41:11 -050082 js, _ := json.Marshal(ofbField)
83 logger.Warnw("ParseOXM Unhandled OxmField", l.Fields{"DeviceID": DeviceID, "OfbField": js})
Don Newtone0d34a82019-11-14 10:58:06 -050084 }
85 return nil, 0
86}
Don Newton7577f072020-01-06 12:41:11 -050087func parseInstructions(ofpInstruction *openflow_13.OfpInstruction, DeviceID string) (ofp.IInstruction, uint16) {
88 if settings.GetDebug(DeviceID) {
89 js, _ := json.Marshal(ofpInstruction)
90 logger.Debugw("parseInstructions called", l.Fields{"DeviceID": DeviceID, "Instruction": js})
91 }
Don Newtone0d34a82019-11-14 10:58:06 -050092 instType := ofpInstruction.Type
93 data := ofpInstruction.GetData()
94 switch instType {
95 case ofp.OFPITWriteMetadata:
96 instruction := ofp.NewInstructionWriteMetadata()
97 instruction.Len = 24
98 metadata := data.(*openflow_13.OfpInstruction_WriteMetadata).WriteMetadata
99 instruction.Metadata = uint64(metadata.Metadata)
100 return instruction, 24
101 case ofp.OFPITMeter:
102 instruction := ofp.NewInstructionMeter()
103 instruction.Len = 8
104 meter := data.(*openflow_13.OfpInstruction_Meter).Meter
105 instruction.MeterId = meter.MeterId
106 return instruction, 8
107 case ofp.OFPITGotoTable:
108 instruction := ofp.NewInstructionGotoTable()
109 instruction.Len = 8
110 gotoTable := data.(*openflow_13.OfpInstruction_GotoTable).GotoTable
111 instruction.TableId = uint8(gotoTable.TableId)
112 return instruction, 8
113 case ofp.OFPITApplyActions:
114 instruction := ofp.NewInstructionApplyActions()
115 var instructionSize uint16
116 instructionSize = 8
117 ofpActions := ofpInstruction.GetActions().Actions
118 var actions []goloxi.IAction
119 for i := 0; i < len(ofpActions); i++ {
120 ofpAction := ofpActions[i]
Don Newton7577f072020-01-06 12:41:11 -0500121 action, actionSize := parseAction(ofpAction, DeviceID)
Don Newtone0d34a82019-11-14 10:58:06 -0500122 actions = append(actions, action)
123 instructionSize += actionSize
Don Newtone0d34a82019-11-14 10:58:06 -0500124
125 }
126 instruction.Actions = actions
127 instruction.SetLen(instructionSize)
Don Newton7577f072020-01-06 12:41:11 -0500128 if settings.GetDebug(DeviceID) {
129 js, _ := json.Marshal(instruction)
130 l.Debugw("parseInstructions returning", l.Fields{"DeviceID": DeviceID,
131 "Size": instructionSize, "ParsedInstruction": js})
132 }
Don Newtone0d34a82019-11-14 10:58:06 -0500133 return instruction, instructionSize
134 }
135 //shouldn't have reached here :<
Don Newtone0d34a82019-11-14 10:58:06 -0500136 return nil, 0
137}
Don Newton7577f072020-01-06 12:41:11 -0500138func parseAction(ofpAction *openflow_13.OfpAction, DeviceID string) (goloxi.IAction, uint16) {
139 if settings.GetDebug(DeviceID) {
140 js, _ := json.Marshal(ofpAction)
141 logger.Debugw("parseAction called", l.Fields{"DeviceID": DeviceID, "Action": js})
142 }
Don Newtone0d34a82019-11-14 10:58:06 -0500143 switch ofpAction.Type {
144 case openflow_13.OfpActionType_OFPAT_OUTPUT:
145 ofpOutputAction := ofpAction.GetOutput()
146 outputAction := ofp.NewActionOutput()
147 outputAction.Port = ofp.Port(ofpOutputAction.Port)
148 outputAction.MaxLen = uint16(ofpOutputAction.MaxLen)
149 outputAction.Len = 16
150 return outputAction, 16
151 case openflow_13.OfpActionType_OFPAT_PUSH_VLAN:
152 ofpPushVlanAction := ofp.NewActionPushVlan()
153 ofpPushVlanAction.Ethertype = uint16(ofpAction.GetPush().Ethertype)
154 ofpPushVlanAction.Len = 8
155 return ofpPushVlanAction, 8
156 case openflow_13.OfpActionType_OFPAT_POP_VLAN:
157 ofpPopVlanAction := ofp.NewActionPopVlan()
158 ofpPopVlanAction.Len = 8
159 return ofpPopVlanAction, 8
160 case openflow_13.OfpActionType_OFPAT_SET_FIELD:
161 ofpActionSetField := ofpAction.GetSetField()
162 setFieldAction := ofp.NewActionSetField()
163
Don Newton7577f072020-01-06 12:41:11 -0500164 iOxm, _ := parseOxm(ofpActionSetField.GetField().GetOfbField(), DeviceID)
Don Newtone0d34a82019-11-14 10:58:06 -0500165 setFieldAction.Field = iOxm
Don Newtonb437c6f2019-12-18 11:51:57 -0500166 setFieldAction.Len = 16
167 return setFieldAction, 16
Don Newtone0d34a82019-11-14 10:58:06 -0500168 default:
169 js, _ := json.Marshal(ofpAction)
Don Newton7577f072020-01-06 12:41:11 -0500170 logger.Warnw("parseAction unknow action", l.Fields{"DeviceID": DeviceID, "Action": js})
Don Newtone0d34a82019-11-14 10:58:06 -0500171 }
172 return nil, 0
173}
174func parsePortStats(port *pb.LogicalPort) ofp.PortStatsEntry {
175 stats := port.OfpPortStats
176 port.OfpPort.GetPortNo()
177 var entry ofp.PortStatsEntry
178 entry.SetPortNo(ofp.Port(port.OfpPort.GetPortNo()))
179 entry.SetRxPackets(stats.GetRxPackets())
180 entry.SetTxPackets(stats.GetTxPackets())
181 entry.SetRxBytes(stats.GetRxBytes())
182 entry.SetTxBytes(stats.GetTxBytes())
183 entry.SetRxDropped(stats.GetRxDropped())
184 entry.SetTxDropped(stats.GetTxDropped())
185 entry.SetRxErrors(stats.GetRxErrors())
186 entry.SetTxErrors(stats.GetTxErrors())
187 entry.SetRxFrameErr(stats.GetRxFrameErr())
188 entry.SetRxOverErr(stats.GetRxOverErr())
189 entry.SetRxCrcErr(stats.GetRxCrcErr())
190 entry.SetCollisions(stats.GetCollisions())
191 entry.SetDurationSec(stats.GetDurationSec())
192 entry.SetDurationNsec(stats.GetDurationNsec())
193 return entry
194}