blob: c07ac5948b69a94ad2fabbd019a58bb53bf43854 [file] [log] [blame]
/*
* Copyright 2022-present Open Networking Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package controller
import (
"fmt"
"strings"
"sync"
)
var mu sync.Mutex
var xid uint32 = 1
// GetXid to get xid
func GetXid() uint32 {
mu.Lock()
defer mu.Unlock()
xid++
return xid
}
// PadString for padding of string
func PadString(value string, padSize int) string {
size := len(value)
nullsNeeded := padSize - size
null := fmt.Sprintf("%c", '\000')
padded := strings.Repeat(null, nullsNeeded)
return fmt.Sprintf("%s%s", value, padded)
}
/*
// extractAction for extract action
func extractAction(action ofp.IAction) *openflow_13.OfpAction {
var ofpAction openflow_13.OfpAction
switch action.GetType() {
case ofp.OFPATOutput:
var outputAction openflow_13.OfpAction_Output
loxiOutputAction := action.(*ofp.ActionOutput)
var output openflow_13.OfpActionOutput
output.Port = uint32(loxiOutputAction.GetPort())
/*
var maxLen uint16
maxLen = loxiOutputAction.GetMaxLen()
output.MaxLen = uint32(maxLen)
*/
/*
output.MaxLen = 0
outputAction.Output = &output
ofpAction.Action = &outputAction
ofpAction.Type = openflow_13.OfpActionType_OFPAT_OUTPUT
case ofp.OFPATCopyTtlOut: //CopyTtltOut
case ofp.OFPATCopyTtlIn: //CopyTtlIn
case ofp.OFPATSetMplsTtl: //SetMplsTtl
case ofp.OFPATDecMplsTtl: //DecMplsTtl
case ofp.OFPATPushVLAN: //PushVlan
var pushVlan openflow_13.OfpAction_Push
loxiPushAction := action.(*ofp.ActionPushVlan)
var push openflow_13.OfpActionPush
push.Ethertype = uint32(loxiPushAction.Ethertype) //TODO This should be available in the fields
pushVlan.Push = &push
ofpAction.Type = openflow_13.OfpActionType_OFPAT_PUSH_VLAN
ofpAction.Action = &pushVlan
case ofp.OFPATPopVLAN: //PopVlan
ofpAction.Type = openflow_13.OfpActionType_OFPAT_POP_VLAN
case ofp.OFPATPushMpls: //PushMpls
case ofp.OFPATPopMpls: //PopMpls
case ofp.OFPATSetQueue: //SetQueue
case ofp.OFPATGroup: //ActionGroup
case ofp.OFPATSetNwTtl: //SetNwTtl
case ofp.OFPATDecNwTtl: //DecNwTtl
case ofp.OFPATSetField: //SetField
ofpAction.Type = openflow_13.OfpActionType_OFPAT_SET_FIELD
var ofpActionForSetField openflow_13.OfpAction_SetField
var ofpActionSetField openflow_13.OfpActionSetField
var ofpOxmField openflow_13.OfpOxmField
ofpOxmField.OxmClass = openflow_13.OfpOxmClass_OFPXMC_OPENFLOW_BASIC
var ofpOxmFieldForOfbField openflow_13.OfpOxmField_OfbField
var ofpOxmOfbField openflow_13.OfpOxmOfbField
loxiSetField := action.(*ofp.ActionSetField)
oxmName := loxiSetField.Field.GetOXMName()
switch oxmName {
//TODO handle set field sith other fields
case "vlan_vid":
ofpOxmOfbField.Type = openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID
var vlanVid openflow_13.OfpOxmOfbField_VlanVid
var VlanVid = loxiSetField.Field.GetOXMValue().(uint16)
vlanVid.VlanVid = uint32(VlanVid)
ofpOxmOfbField.Value = &vlanVid
}
ofpOxmFieldForOfbField.OfbField = &ofpOxmOfbField
ofpOxmField.Field = &ofpOxmFieldForOfbField
ofpActionSetField.Field = &ofpOxmField
ofpActionForSetField.SetField = &ofpActionSetField
ofpAction.Action = &ofpActionForSetField
case ofp.OFPATPushPbb: //PushPbb
case ofp.OFPATPopPbb: //PopPbb
case ofp.OFPATExperimenter: //Experimenter
}
return &ofpAction
}
// parseOxm for parsing OxmOfb field
func parseOxm(ofbField *openflow_13.OfpOxmOfbField, DeviceID string) (goloxi.IOxm, uint16) {
switch ofbField.Type {
case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_IN_PORT:
ofpInPort := ofp.NewOxmInPort()
val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_Port)
ofpInPort.Value = ofp.Port(val.Port)
return ofpInPort, 4
case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
ofpEthType := ofp.NewOxmEthType()
val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_EthType)
ofpEthType.Value = ofp.EthernetType(val.EthType)
return ofpEthType, 2
case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_IN_PHY_PORT:
ofpInPhyPort := ofp.NewOxmInPhyPort()
val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_PhysicalPort)
ofpInPhyPort.Value = ofp.Port(val.PhysicalPort)
return ofpInPhyPort, 4
case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
ofpIPProto := ofp.NewOxmIpProto()
val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_IpProto)
ofpIPProto.Value = ofp.IpPrototype(val.IpProto)
return ofpIPProto, 1
case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
ofpUDPSrc := ofp.NewOxmUdpSrc()
val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_UdpSrc)
ofpUDPSrc.Value = uint16(val.UdpSrc)
return ofpUDPSrc, 2
case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
ofpUDPDst := ofp.NewOxmUdpDst()
val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_UdpDst)
ofpUDPDst.Value = uint16(val.UdpDst)
return ofpUDPDst, 2
case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
ofpVlanVid := ofp.NewOxmVlanVid()
val := ofbField.GetValue()
if val == nil {
ofpVlanVid.Value = uint16(0)
return ofpVlanVid, 2
}
vlanID := val.(*openflow_13.OfpOxmOfbField_VlanVid)
if ofbField.HasMask {
ofpVlanVidMasked := ofp.NewOxmVlanVidMasked()
valMask := ofbField.GetMask()
vlanMask := valMask.(*openflow_13.OfpOxmOfbField_VlanVidMask)
if vlanID.VlanVid == 4096 && vlanMask.VlanVidMask == 4096 {
ofpVlanVidMasked.Value = uint16(vlanID.VlanVid)
ofpVlanVidMasked.ValueMask = uint16(vlanMask.VlanVidMask)
} else {
ofpVlanVidMasked.Value = uint16(vlanID.VlanVid) | 0x1000
ofpVlanVidMasked.ValueMask = uint16(vlanMask.VlanVidMask)
}
return ofpVlanVidMasked, 4
}
ofpVlanVid.Value = uint16(vlanID.VlanVid) | 0x1000
return ofpVlanVid, 2
case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
ofpMetadata := ofp.NewOxmMetadata()
val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_TableMetadata)
ofpMetadata.Value = val.TableMetadata
return ofpMetadata, 8
default:
}
return nil, 0
}
// parseInstructions for parsing of instructions
func parseInstructions(ofpInstruction *openflow_13.OfpInstruction, DeviceID string) (ofp.IInstruction, uint16) {
instType := ofpInstruction.Type
data := ofpInstruction.GetData()
switch instType {
case ofp.OFPITWriteMetadata:
instruction := ofp.NewInstructionWriteMetadata()
instruction.Len = 24
metadata := data.(*openflow_13.OfpInstruction_WriteMetadata).WriteMetadata
instruction.Metadata = uint64(metadata.Metadata)
return instruction, 24
case ofp.OFPITMeter:
instruction := ofp.NewInstructionMeter()
instruction.Len = 8
meter := data.(*openflow_13.OfpInstruction_Meter).Meter
instruction.MeterId = meter.MeterId
return instruction, 8
case ofp.OFPITGotoTable:
instruction := ofp.NewInstructionGotoTable()
instruction.Len = 8
gotoTable := data.(*openflow_13.OfpInstruction_GotoTable).GotoTable
instruction.TableId = uint8(gotoTable.TableId)
return instruction, 8
case ofp.OFPITApplyActions:
instruction := ofp.NewInstructionApplyActions()
var instructionSize uint16
instructionSize = 8
//ofpActions := ofpInstruction.GetActions().Actions
var actions []goloxi.IAction
for _, ofpAction := range ofpInstruction.GetActions().Actions {
action, actionSize := parseAction(ofpAction, DeviceID)
actions = append(actions, action)
instructionSize += actionSize
}
instruction.Actions = actions
instruction.SetLen(instructionSize)
return instruction, instructionSize
}
//shouldn't have reached here :<
return nil, 0
}
// parseAction for parsing of actions
func parseAction(ofpAction *openflow_13.OfpAction, DeviceID string) (goloxi.IAction, uint16) {
switch ofpAction.Type {
case openflow_13.OfpActionType_OFPAT_OUTPUT:
ofpOutputAction := ofpAction.GetOutput()
outputAction := ofp.NewActionOutput()
outputAction.Port = ofp.Port(ofpOutputAction.Port)
outputAction.MaxLen = uint16(ofpOutputAction.MaxLen)
outputAction.Len = 16
return outputAction, 16
case openflow_13.OfpActionType_OFPAT_PUSH_VLAN:
ofpPushVlanAction := ofp.NewActionPushVlan()
ofpPushVlanAction.Ethertype = uint16(ofpAction.GetPush().Ethertype)
ofpPushVlanAction.Len = 8
return ofpPushVlanAction, 8
case openflow_13.OfpActionType_OFPAT_POP_VLAN:
ofpPopVlanAction := ofp.NewActionPopVlan()
ofpPopVlanAction.Len = 8
return ofpPopVlanAction, 8
case openflow_13.OfpActionType_OFPAT_SET_FIELD:
ofpActionSetField := ofpAction.GetSetField()
setFieldAction := ofp.NewActionSetField()
iOxm, _ := parseOxm(ofpActionSetField.GetField().GetOfbField(), DeviceID)
setFieldAction.Field = iOxm
setFieldAction.Len = 16
return setFieldAction, 16
default:
}
return nil, 0
}
// parsePortStats for parsing of port stats
func parsePortStats(port *voltha.LogicalPort) *ofp.PortStatsEntry {
stats := port.OfpPortStats
port.OfpPort.GetPortNo()
var entry ofp.PortStatsEntry
entry.SetPortNo(ofp.Port(port.OfpPort.GetPortNo()))
entry.SetRxPackets(stats.GetRxPackets())
entry.SetTxPackets(stats.GetTxPackets())
entry.SetRxBytes(stats.GetRxBytes())
entry.SetTxBytes(stats.GetTxBytes())
entry.SetRxDropped(stats.GetRxDropped())
entry.SetTxDropped(stats.GetTxDropped())
entry.SetRxErrors(stats.GetRxErrors())
entry.SetTxErrors(stats.GetTxErrors())
entry.SetRxFrameErr(stats.GetRxFrameErr())
entry.SetRxOverErr(stats.GetRxOverErr())
entry.SetRxCrcErr(stats.GetRxCrcErr())
entry.SetCollisions(stats.GetCollisions())
entry.SetDurationSec(stats.GetDurationSec())
entry.SetDurationNsec(stats.GetDurationNsec())
return &entry
}*/