functional version
Change-Id: Ic089d1fc7a2c6bc51e00371c993a6fc6aaa17863
diff --git a/openflow/feature.go b/openflow/feature.go
index 6a22836..beb134d 100644
--- a/openflow/feature.go
+++ b/openflow/feature.go
@@ -19,10 +19,11 @@
import (
"context"
"encoding/json"
- ofp "github.com/donNewtonAlpha/goloxi/of13"
- "github.com/opencord/voltha-protos/go/common"
- pb "github.com/opencord/voltha-protos/go/voltha"
"log"
+
+ ofp "github.com/donNewtonAlpha/goloxi/of13"
+ "github.com/opencord/voltha-protos/v2/go/common"
+ pb "github.com/opencord/voltha-protos/v2/go/voltha"
)
func handleFeatureRequest(request *ofp.FeaturesRequest, deviceId string, client *Client) error {
diff --git a/openflow/flowMod.go b/openflow/flowMod.go
index 2508bde..53ec8c9 100644
--- a/openflow/flowMod.go
+++ b/openflow/flowMod.go
@@ -22,8 +22,8 @@
"log"
ofp "github.com/donNewtonAlpha/goloxi/of13"
- "github.com/opencord/voltha-protos/go/openflow_13"
- pb "github.com/opencord/voltha-protos/go/voltha"
+ "github.com/opencord/voltha-protos/v2/go/openflow_13"
+ pb "github.com/opencord/voltha-protos/v2/go/voltha"
)
var oxmMap = map[string]int32{
@@ -79,7 +79,8 @@
flowMod.Cookie = flowAdd.Cookie
flowMod.CookieMask = flowAdd.CookieMask
flowMod.TableId = uint32(flowAdd.TableId)
- flowMod.Command = pb.OfpFlowModCommand_OFPFC_ADD
+ //flowMod.Command = pb.OfpFlowModCommand_OFPFC_ADD
+ flowMod.Command = 0
flowMod.IdleTimeout = uint32(flowAdd.IdleTimeout)
flowMod.HardTimeout = uint32(flowAdd.HardTimeout)
flowMod.Priority = uint32(flowAdd.Priority)
@@ -87,6 +88,8 @@
flowMod.OutPort = uint32(flowAdd.OutPort)
flowMod.OutGroup = uint32(flowAdd.OutGroup)
flowMod.Flags = uint32(flowAdd.Flags)
+ js, _ = json.Marshal(flowMod)
+ log.Printf("HANDLE FLOW ADD FLOW_MOD %s", js)
inMatch := flowAdd.Match
var flowMatch pb.OfpMatch
flowMatch.Type = pb.OfpMatchType(inMatch.GetType())
@@ -149,7 +152,7 @@
value.UdpDst = uint32(udpDst)
field.Value = &value
case pb.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
- vid := val.(uint16) & 0xfff
+ vid := (val.(uint16) & 0xfff) | 0x1000
var value pb.OfpOxmOfbField_VlanVid
value.VlanVid = uint32(vid)
field.Value = &value
@@ -250,4 +253,165 @@
js, _ := json.Marshal(flowDeleteStrict)
log.Printf("handleFlowDeleteStrict called with %s", js)
+ var flowUpdate openflow_13.FlowTableUpdate
+ flowUpdate.Id = deviceId
+ var flowMod pb.OfpFlowMod
+ flowMod.Cookie = flowDeleteStrict.Cookie
+ flowMod.CookieMask = flowDeleteStrict.CookieMask
+ flowMod.TableId = uint32(flowDeleteStrict.TableId)
+ flowMod.Command = pb.OfpFlowModCommand_OFPFC_DELETE_STRICT
+ flowMod.IdleTimeout = uint32(flowDeleteStrict.IdleTimeout)
+ flowMod.HardTimeout = uint32(flowDeleteStrict.HardTimeout)
+ flowMod.Priority = uint32(flowDeleteStrict.Priority)
+ flowMod.BufferId = flowDeleteStrict.BufferId
+ flowMod.OutPort = uint32(flowDeleteStrict.OutPort)
+ flowMod.OutGroup = uint32(flowDeleteStrict.OutGroup)
+ flowMod.Flags = uint32(flowDeleteStrict.Flags)
+ inMatch := flowDeleteStrict.Match
+ var flowMatch pb.OfpMatch
+ flowMatch.Type = pb.OfpMatchType(inMatch.GetType())
+ var oxmList []*pb.OfpOxmField
+ inOxmList := inMatch.GetOxmList()
+ for i := 0; i < len(inOxmList); i++ {
+ oxmField := inOxmList[i]
+ j, _ := json.Marshal(oxmField)
+
+ name := oxmMap[oxmField.GetOXMName()]
+ log.Printf("\n\n\n %s %d %s\n\n\n", j, name, oxmField.GetOXMName())
+
+ val := oxmField.GetOXMValue()
+ var ofpOxmField pb.OfpOxmField
+ ofpOxmField.OxmClass = ofp.OFPXMCOpenflowBasic
+ var field pb.OfpOxmOfbField
+
+ field.Type = pb.OxmOfbFieldTypes(name)
+ log.Println("****\nFieldType: " + openflow_13.OxmOfbFieldTypes_name[name] + "\n\n\n\n")
+
+ var x openflow_13.OfpOxmField_OfbField
+ x.OfbField = &field
+ ofpOxmField.Field = &x
+
+ switch pb.OxmOfbFieldTypes(name) {
+ case pb.OxmOfbFieldTypes_OFPXMT_OFB_IN_PORT:
+ port := val.(ofp.Port)
+ var value pb.OfpOxmOfbField_Port
+ value.Port = uint32(port)
+ field.Value = &value
+ case pb.OxmOfbFieldTypes_OFPXMT_OFB_IN_PHY_PORT:
+ phyPort := val.(uint32)
+ var value pb.OfpOxmOfbField_PhysicalPort
+ value.PhysicalPort = phyPort
+ field.Value = &value
+ case pb.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
+ metadata := val.(uint64)
+ var value pb.OfpOxmOfbField_TableMetadata
+ value.TableMetadata = metadata
+ field.Value = &value
+ case pb.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
+ ethType := val.(ofp.EthernetType)
+ var value pb.OfpOxmOfbField_EthType
+ value.EthType = uint32(ethType)
+ field.Value = &value
+ case pb.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
+ proto := val.(ofp.IpPrototype)
+ var value pb.OfpOxmOfbField_IpProto
+ value.IpProto = uint32(proto)
+ field.Value = &value
+ case pb.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
+ udpSrc := val.(uint16)
+ var value pb.OfpOxmOfbField_UdpSrc
+ value.UdpSrc = uint32(udpSrc)
+ log.Printf("udpSrc %v", udpSrc)
+ field.Value = &value
+ case pb.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
+ udpDst := val.(uint16)
+ var value pb.OfpOxmOfbField_UdpDst
+ value.UdpDst = uint32(udpDst)
+ field.Value = &value
+ case pb.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
+ //vid := (val.(uint16) & 0xfff)|0x1000
+ vid := val.(uint16)
+ //vid := val.(uint16) & 0xfff
+ var value pb.OfpOxmOfbField_VlanVid
+ value.VlanVid = uint32(vid)
+ field.Value = &value
+ }
+ oxmList = append(oxmList, &ofpOxmField)
+ }
+ flowMatch.OxmFields = oxmList
+ flowMod.Match = &flowMatch
+ /*var instructions []*pb.OfpInstruction
+ ofpInstructions := flowDeleteStrict.GetInstructions()
+ for i := 0; i < len(ofpInstructions); i++ {
+ var instruction pb.OfpInstruction
+ ofpInstruction := ofpInstructions[i]
+ instructionType := ofpInstruction.GetType()
+ instruction.Type = uint32(instructionType)
+ switch instructionType {
+ case ofp.OFPITGotoTable:
+ goToTable := ofpInstruction.(ofp.IInstructionGotoTable)
+ var ofpGoToTable openflow_13.OfpInstruction_GotoTable
+ var oGoToTable openflow_13.OfpInstructionGotoTable
+ ofpGoToTable.GotoTable = &oGoToTable
+ ofpGoToTable.GotoTable.TableId = uint32(goToTable.GetTableId())
+ instruction.Data = &ofpGoToTable
+ case ofp.OFPITWriteMetadata:
+ writeMetaData := ofpInstruction.(ofp.IInstructionWriteMetadata)
+ var ofpWriteMetadata openflow_13.OfpInstruction_WriteMetadata
+ var writeMetadata openflow_13.OfpInstructionWriteMetadata
+ ofpWriteMetadata.WriteMetadata = &writeMetadata
+ ofpWriteMetadata.WriteMetadata.Metadata = writeMetaData.GetMetadata()
+ ofpWriteMetadata.WriteMetadata.MetadataMask = writeMetaData.GetMetadataMask()
+ instruction.Data = &ofpWriteMetadata
+ case ofp.OFPITWriteActions:
+ writeAction := ofpInstruction.(ofp.IInstructionWriteActions)
+ var ofpInstructionActions openflow_13.OfpInstruction_Actions
+ var ofpActions []*openflow_13.OfpAction
+ actions := writeAction.GetActions()
+ for i := 0; i < len(actions); i++ {
+ action := actions[i]
+ ofpAction := extractAction(action)
+ ofpActions = append(ofpActions, ofpAction)
+ }
+ instruction.Data = &ofpInstructionActions
+ case ofp.OFPITApplyActions:
+ applyAction := ofpInstruction.(ofp.IInstructionApplyActions)
+ var ofpInstructionActions openflow_13.OfpInstruction_Actions
+ var ofpActions []*openflow_13.OfpAction
+ actions := applyAction.GetActions()
+ for i := 0; i < len(actions); i++ {
+ action := actions[i]
+ ofpAction := extractAction(action)
+ ofpActions = append(ofpActions, ofpAction)
+ }
+ var actionsHolder openflow_13.OfpInstructionActions
+ actionsHolder.Actions = ofpActions
+ ofpInstructionActions.Actions = &actionsHolder
+ instruction.Data = &ofpInstructionActions
+ case ofp.OFPITMeter:
+ var instructionMeter = ofpInstruction.(ofp.IInstructionMeter)
+ var meterInstruction openflow_13.OfpInstruction_Meter
+ var meter openflow_13.OfpInstructionMeter
+
+ meter.MeterId = instructionMeter.GetMeterId()
+ meterInstruction.Meter = &meter
+ instruction.Data = &meterInstruction
+ }
+ instructions = append(instructions, &instruction)
+ }
+
+ flowMod.Instructions = instructions
+
+ */
+ flowUpdate.FlowMod = &flowMod
+ grpcClient := *getGrpcClient()
+ flowUpdateJs, _ := json.Marshal(flowUpdate)
+ log.Printf("FLOW UPDATE %s", flowUpdateJs)
+ empty, err := grpcClient.UpdateLogicalDeviceFlowTable(context.Background(), &flowUpdate)
+ if err != nil {
+ log.Printf("ERROR DOING FLOW MOD ADD %v", err)
+ }
+ emptyJs, _ := json.Marshal(empty)
+ log.Printf("FLOW MOD RESPONSE %s", emptyJs)
+
}
diff --git a/openflow/meter.go b/openflow/meter.go
index 43d690e..7e9d816 100644
--- a/openflow/meter.go
+++ b/openflow/meter.go
@@ -18,7 +18,7 @@
import (
"encoding/json"
ofp "github.com/donNewtonAlpha/goloxi/of13"
- "github.com/opencord/voltha-protos/go/openflow_13"
+ "github.com/opencord/voltha-protos/v2/go/openflow_13"
"golang.org/x/net/context"
"log"
)
@@ -38,19 +38,14 @@
ofpBands := request.GetMeters()
for i := 0; i < len(ofpBands); i++ {
ofpBand := ofpBands[i]
-
bandType := ofpBand.GetType()
var band openflow_13.OfpMeterBandHeader
switch bandType {
case ofp.OFPMBTDrop:
ofpDrop := ofpBand.(ofp.IMeterBandDrop)
- band.BurstSize = ofpDrop.GetBurstSize()
band.Type = openflow_13.OfpMeterBandType_OFPMBT_DROP
band.Rate = ofpDrop.GetRate()
- var meterBandHeaderDrop openflow_13.OfpMeterBandHeader_Drop
- var drop openflow_13.OfpMeterBandDrop
- meterBandHeaderDrop.Drop = &drop
- band.Data = &meterBandHeaderDrop
+ band.BurstSize = ofpDrop.GetBurstSize()
case ofp.OFPMBTDSCPRemark:
ofpDscpRemark := ofpBand.(ofp.IMeterBandDscpRemark)
var dscpRemark openflow_13.OfpMeterBandDscpRemark
@@ -58,9 +53,12 @@
band.BurstSize = ofpDscpRemark.GetBurstSize()
band.Rate = ofpDscpRemark.GetRate()
dscpRemark.PrecLevel = uint32(ofpDscpRemark.GetPrecLevel())
- var meterBandHeaderDscp openflow_13.OfpMeterBandHeader_DscpRemark
- meterBandHeaderDscp.DscpRemark = &dscpRemark
- band.Data = &meterBandHeaderDscp
+ /*
+ var meterBandHeaderDscp openflow_13.OfpMeterBandHeader_DscpRemark
+ meterBandHeaderDscp.DscpRemark = &dscpRemark
+ band.Data = &meterBandHeaderDscp
+
+ */
case ofp.OFPMBTExperimenter:
ofpExperimenter := ofpBand.(ofp.IMeterBandExperimenter)
var experimenter openflow_13.OfpMeterBandExperimenter
@@ -68,9 +66,12 @@
band.Type = openflow_13.OfpMeterBandType_OFPMBT_EXPERIMENTER
band.BurstSize = ofpExperimenter.GetBurstSize()
band.Rate = ofpExperimenter.GetRate()
- var meterBandHeaderExperimenter openflow_13.OfpMeterBandHeader_Experimenter
- meterBandHeaderExperimenter.Experimenter = &experimenter
- band.Data = &meterBandHeaderExperimenter
+ /*
+ var meterBandHeaderExperimenter openflow_13.OfpMeterBandHeader_Experimenter
+ meterBandHeaderExperimenter.Experimenter = &experimenter
+ band.Data = &meterBandHeaderExperimenter
+
+ */
}
bands = append(bands, &band)
}
diff --git a/openflow/openflowClient.go b/openflow/openflowClient.go
index f7e3b72..29cd423 100644
--- a/openflow/openflowClient.go
+++ b/openflow/openflowClient.go
@@ -23,7 +23,7 @@
"github.com/donNewtonAlpha/goloxi"
ofp "github.com/donNewtonAlpha/goloxi/of13"
- pb "github.com/opencord/voltha-protos/go/voltha"
+ pb "github.com/opencord/voltha-protos/v2/go/voltha"
"log"
"net"
@@ -55,6 +55,7 @@
if e != nil {
errMessage := fmt.Errorf("Unable to resolve %s", addressLine)
fmt.Println(errMessage)
+ return
}
for {
if client.KeepRunning {
@@ -64,26 +65,11 @@
log.Fatalf("unable to connect to %v", raddr)
}
defer conn.Close()
- hello := ofp.NewHello()
- hello.Xid = uint32(GetXid())
- var elements []ofp.IHelloElem
-
- elem := ofp.NewHelloElemVersionbitmap()
- elem.SetType(ofp.OFPHETVersionbitmap)
- elem.SetLength(8)
- var bitmap = ofp.Uint32{Value: 16}
- bitmaps := []*ofp.Uint32{&bitmap}
-
- elem.SetBitmaps(bitmaps)
-
- elements = append(elements, elem)
-
- hello.SetElements(elements)
- e = client.SendMessage(hello)
- if e != nil {
- log.Fatal(e)
- }
+ client.sayHello()
for {
+ if !client.KeepRunning {
+ return
+ }
buf := make([]byte, 1500)
read, e := conn.Read(buf)
if e != nil {
@@ -91,9 +77,7 @@
break
}
decoder := goloxi.NewDecoder(buf)
- log.Printf("decoder offset %d baseOffset %d", decoder.Offset(), decoder.BaseOffset())
header, e := ofp.DecodeHeader(decoder)
- log.Printf("received packet read: %d", read)
if e != nil {
log.Printf("decodeheader threw error %v", e)
@@ -103,7 +87,6 @@
client.parseHeader(header, buf) //first one is ready
len := header.GetLength()
if len < uint16(read) {
- log.Printf("Len %d was less than read %d", len, read)
for {
read = read - int(len)
newBuf := buf[len:]
@@ -117,10 +100,8 @@
len = newHeader.GetLength()
client.parseHeader(newHeader, newBuf)
if read == int(len) {
- log.Printf(" not continuing read %d len %d", read, len)
break
} else {
- log.Printf("continuing read %d len %d", read, len)
}
buf = newBuf
}
@@ -133,14 +114,32 @@
break
}
}
+func (client *Client) sayHello() {
+ hello := ofp.NewHello()
+ hello.Xid = uint32(GetXid())
+ var elements []ofp.IHelloElem
+
+ elem := ofp.NewHelloElemVersionbitmap()
+ elem.SetType(ofp.OFPHETVersionbitmap)
+ elem.SetLength(8)
+ var bitmap = ofp.Uint32{Value: 16}
+ bitmaps := []*ofp.Uint32{&bitmap}
+
+ elem.SetBitmaps(bitmaps)
+
+ elements = append(elements, elem)
+
+ hello.SetElements(elements)
+ e := client.SendMessage(hello)
+ if e != nil {
+ log.Fatal(e)
+ }
+}
func (client *Client) parseHeader(header ofp.IHeader, buf []byte) {
-
- log.Printf("parseHeader called with type %d", header.GetType())
switch header.GetType() {
case ofp.OFPTHello:
- x := header.(*ofp.Hello)
- log.Printf("helloMessage : %+v", x)
+ //x := header.(*ofp.Hello)
case ofp.OFPTError:
errMsg := header.(*ofp.ErrorMsg)
go handleErrMsg(errMsg)
diff --git a/openflow/packet.go b/openflow/packet.go
index 66949cd..3229623 100644
--- a/openflow/packet.go
+++ b/openflow/packet.go
@@ -19,7 +19,7 @@
import (
"encoding/json"
ofp "github.com/donNewtonAlpha/goloxi/of13"
- pb "github.com/opencord/voltha-protos/go/voltha"
+ pb "github.com/opencord/voltha-protos/v2/go/voltha"
"log"
)
@@ -34,6 +34,8 @@
for i := 0; i < len(inActions); i++ {
action := inActions[i]
newAction := extractAction(action)
+ js, _ := json.Marshal(newAction)
+ log.Printf("PACKET_OUT ACTION %s", js)
/*var newAction = pb.OfpAction{}
newAction.Type = pb.OfpActionType(action.GetType())
action.
diff --git a/openflow/parseGrpcReturn.go b/openflow/parseGrpcReturn.go
index 706e9a7..072bdcf 100644
--- a/openflow/parseGrpcReturn.go
+++ b/openflow/parseGrpcReturn.go
@@ -17,15 +17,17 @@
import (
"encoding/json"
- "github.com/donNewtonAlpha/goloxi"
- ofp "github.com/donNewtonAlpha/goloxi/of13"
- "github.com/opencord/voltha-protos/go/openflow_13"
- pb "github.com/opencord/voltha-protos/go/voltha"
"log"
"unsafe"
+
+ "github.com/donNewtonAlpha/goloxi"
+ ofp "github.com/donNewtonAlpha/goloxi/of13"
+ "github.com/opencord/voltha-protos/v2/go/openflow_13"
+ pb "github.com/opencord/voltha-protos/v2/go/voltha"
)
func parseOxm(ofbField *openflow_13.OfpOxmOfbField) (goloxi.IOxm, uint16) {
+ log.Printf("PARSE OXM")
switch ofbField.Type {
case pb.OxmOfbFieldTypes_OFPXMT_OFB_IN_PORT:
ofpInPort := ofp.NewOxmInPort()
@@ -62,10 +64,12 @@
val := ofbField.GetValue()
if val != nil {
vlanId := val.(*openflow_13.OfpOxmOfbField_VlanVid)
- ofpVlanVid.Value = uint16(vlanId.VlanVid) + 0x1000
+ ofpVlanVid.Value = uint16(vlanId.VlanVid) | 0x1000
} else {
ofpVlanVid.Value = uint16(0)
}
+ js, _ := json.Marshal(ofpVlanVid)
+ log.Printf("PARSE OXM VLAN VID %s", js)
return ofpVlanVid, 2
case pb.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
ofpMetadata := ofp.NewOxmMetadata()
@@ -153,8 +157,8 @@
iOxm, _ := parseOxm(ofpActionSetField.GetField().GetOfbField())
setFieldAction.Field = iOxm
- setFieldAction.Len = 10
- return setFieldAction, 10
+ setFieldAction.Len = 16
+ return setFieldAction, 16
default:
js, _ := json.Marshal(ofpAction)
log.Printf("UNKNOWN ACTION %s", js)
diff --git a/openflow/stats.go b/openflow/stats.go
index 0218463..54a23de 100644
--- a/openflow/stats.go
+++ b/openflow/stats.go
@@ -24,11 +24,11 @@
"net"
"unsafe"
- "github.com/opencord/voltha-protos/go/openflow_13"
+ "github.com/opencord/voltha-protos/v2/go/openflow_13"
"github.com/donNewtonAlpha/goloxi"
ofp "github.com/donNewtonAlpha/goloxi/of13"
- "github.com/opencord/voltha-protos/go/common"
+ "github.com/opencord/voltha-protos/v2/go/common"
)
func handleStatsRequest(request ofp.IHeader, statType uint16, deviceId string, client *Client) error {
@@ -47,11 +47,14 @@
case ofp.OFPSTFlow:
statsReq := request.(*ofp.FlowStatsRequest)
- response, _ := handleFlowStatsRequest(statsReq, id)
+ response, err := handleFlowStatsRequest(statsReq, id)
+ if err != nil {
+ return err
+ }
response.Length = uint16(unsafe.Sizeof(*response))
jResponse, _ := json.Marshal(response)
log.Printf("HANDLE FLOW STATS REQUEST response\n\n\n %s \n\n\n", jResponse)
- err := client.SendMessage(response)
+ err = client.SendMessage(response)
if err != nil {
return err
}
@@ -239,6 +242,7 @@
if size%8 != 0 {
size = ((size / 8) + 1) * 8
}
+
log.Printf("Size is %d", size)
entrySize += size
entry.SetMatch(*match)
diff --git a/openflow/utils.go b/openflow/utils.go
index aba7400..7994fd2 100644
--- a/openflow/utils.go
+++ b/openflow/utils.go
@@ -24,7 +24,7 @@
"sync"
ofp "github.com/donNewtonAlpha/goloxi/of13"
- "github.com/opencord/voltha-protos/go/openflow_13"
+ "github.com/opencord/voltha-protos/v2/go/openflow_13"
)
var mu sync.Mutex
@@ -51,11 +51,19 @@
var outputAction openflow_13.OfpAction_Output
loxiOutputAction := action.(*ofp.ActionOutput)
var output openflow_13.OfpActionOutput
- output.Port = uint32(loxiOutputAction.Port)
- output.MaxLen = uint32(loxiOutputAction.MaxLen)
+ 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
+ js, _ := json.Marshal(outputAction)
+ log.Printf("EXTRACT ACTION %s", js)
case ofp.OFPATCopyTtlOut: //CopyTtltOut
case ofp.OFPATCopyTtlIn: //CopyTtlIn
case ofp.OFPATSetMplsTtl: //SetMplsTtl
@@ -105,6 +113,7 @@
ofpActionSetField.Field = &ofpOxmField
ofpAction_SetField.SetField = &ofpActionSetField
ofpAction.Action = &ofpAction_SetField
+
case ofp.OFPATPushPbb: //PushPbb
case ofp.OFPATPopPbb: //PopPbb
case ofp.OFPATExperimenter: //Experimenter