Change goloxi dependency to opencord/goloxi.
Remove explicit length calculation.
Change-Id: Ie3c7643ed0d1e076e85f050d2b3e354b77b9eb0f
diff --git a/internal/pkg/openflow/barrier.go b/internal/pkg/openflow/barrier.go
index 4775d2c..deba220 100644
--- a/internal/pkg/openflow/barrier.go
+++ b/internal/pkg/openflow/barrier.go
@@ -18,7 +18,7 @@
import (
"encoding/json"
- ofp "github.com/donNewtonAlpha/goloxi/of13"
+ ofp "github.com/opencord/goloxi/of13"
"github.com/opencord/voltha-lib-go/v3/pkg/log"
)
diff --git a/internal/pkg/openflow/client.go b/internal/pkg/openflow/client.go
index 3f48e0c..5b44fa4 100644
--- a/internal/pkg/openflow/client.go
+++ b/internal/pkg/openflow/client.go
@@ -22,7 +22,7 @@
"sync"
"time"
- ofp "github.com/donNewtonAlpha/goloxi/of13"
+ ofp "github.com/opencord/goloxi/of13"
"github.com/opencord/ofagent-go/internal/pkg/holder"
"github.com/opencord/voltha-lib-go/v3/pkg/log"
"github.com/opencord/voltha-protos/v3/go/voltha"
diff --git a/internal/pkg/openflow/connection.go b/internal/pkg/openflow/connection.go
index af388b2..209990d 100644
--- a/internal/pkg/openflow/connection.go
+++ b/internal/pkg/openflow/connection.go
@@ -25,8 +25,8 @@
"net"
"time"
- "github.com/donNewtonAlpha/goloxi"
- ofp "github.com/donNewtonAlpha/goloxi/of13"
+ "github.com/opencord/goloxi"
+ ofp "github.com/opencord/goloxi/of13"
"github.com/opencord/ofagent-go/internal/pkg/holder"
"github.com/opencord/voltha-lib-go/v3/pkg/log"
"github.com/opencord/voltha-protos/v3/go/voltha"
@@ -240,11 +240,20 @@
// Read 8 bytes, the standard OF header
read, err := io.ReadFull(fromController, headerBuf)
if err != nil {
- logger.Errorw("bad-of-header",
- log.Fields{
- "byte-count": read,
- "device-id": ofc.DeviceID,
- "error": err})
+ if err == io.EOF {
+ logger.Infow("controller-disconnected",
+ log.Fields{
+ "device-id": ofc.DeviceID,
+ "controller": ofc.OFControllerEndPoint,
+ })
+ } else {
+ logger.Errorw("bad-of-header",
+ log.Fields{
+ "byte-count": read,
+ "device-id": ofc.DeviceID,
+ "controller": ofc.OFControllerEndPoint,
+ "error": err})
+ }
break top
}
diff --git a/internal/pkg/openflow/echo.go b/internal/pkg/openflow/echo.go
index 7358a0f..3b1f774 100644
--- a/internal/pkg/openflow/echo.go
+++ b/internal/pkg/openflow/echo.go
@@ -18,7 +18,7 @@
import (
"encoding/json"
- ofp "github.com/donNewtonAlpha/goloxi/of13"
+ ofp "github.com/opencord/goloxi/of13"
"github.com/opencord/voltha-lib-go/v3/pkg/log"
)
diff --git a/internal/pkg/openflow/error.go b/internal/pkg/openflow/error.go
index 0472ad8..d7b4e43 100644
--- a/internal/pkg/openflow/error.go
+++ b/internal/pkg/openflow/error.go
@@ -18,7 +18,7 @@
import (
"encoding/json"
- ofp "github.com/donNewtonAlpha/goloxi/of13"
+ ofp "github.com/opencord/goloxi/of13"
"github.com/opencord/voltha-lib-go/v3/pkg/log"
)
diff --git a/internal/pkg/openflow/feature.go b/internal/pkg/openflow/feature.go
index 99da50c..d897958 100644
--- a/internal/pkg/openflow/feature.go
+++ b/internal/pkg/openflow/feature.go
@@ -20,7 +20,7 @@
"context"
"encoding/json"
- ofp "github.com/donNewtonAlpha/goloxi/of13"
+ ofp "github.com/opencord/goloxi/of13"
"github.com/opencord/voltha-lib-go/v3/pkg/log"
"github.com/opencord/voltha-protos/v3/go/common"
)
diff --git a/internal/pkg/openflow/flowMod.go b/internal/pkg/openflow/flowMod.go
index 08c0b98..bd8ea4a 100644
--- a/internal/pkg/openflow/flowMod.go
+++ b/internal/pkg/openflow/flowMod.go
@@ -20,9 +20,7 @@
"context"
"encoding/binary"
"encoding/json"
- "unsafe"
-
- ofp "github.com/donNewtonAlpha/goloxi/of13"
+ ofp "github.com/opencord/goloxi/of13"
"github.com/opencord/voltha-lib-go/v3/pkg/log"
"github.com/opencord/voltha-protos/v3/go/openflow_13"
"github.com/opencord/voltha-protos/v3/go/voltha"
@@ -261,7 +259,6 @@
binary.BigEndian.PutUint64(cookie, flowAdd.Cookie)
bs = append(bs, cookie...)
message.SetData(bs)
- message.Length = uint16(unsafe.Sizeof(*message))
err := ofc.SendMessage(message)
if err != nil {
logger.Errorw("Error reporting failure of FlowUpdate to controller",
diff --git a/internal/pkg/openflow/getConfig.go b/internal/pkg/openflow/getConfig.go
index 6425246..26f9f89 100644
--- a/internal/pkg/openflow/getConfig.go
+++ b/internal/pkg/openflow/getConfig.go
@@ -18,7 +18,7 @@
import (
"encoding/json"
- ofp "github.com/donNewtonAlpha/goloxi/of13"
+ ofp "github.com/opencord/goloxi/of13"
"github.com/opencord/voltha-lib-go/v3/pkg/log"
)
diff --git a/internal/pkg/openflow/group.go b/internal/pkg/openflow/group.go
index a1e09c7..b9d107b 100644
--- a/internal/pkg/openflow/group.go
+++ b/internal/pkg/openflow/group.go
@@ -18,8 +18,8 @@
import (
"context"
- "github.com/donNewtonAlpha/goloxi"
- ofp "github.com/donNewtonAlpha/goloxi/of13"
+ "github.com/opencord/goloxi"
+ ofp "github.com/opencord/goloxi/of13"
"github.com/opencord/voltha-lib-go/v3/pkg/log"
"github.com/opencord/voltha-protos/v3/go/openflow_13"
"github.com/opencord/voltha-protos/v3/go/voltha"
@@ -125,11 +125,8 @@
outBuckets := make([]*ofp.Bucket, len(buckets))
for i, bucket := range buckets {
- actions, length := volthaActionsToOpenflow(bucket.Actions)
+ actions := volthaActionsToOpenflow(bucket.Actions)
b := &ofp.Bucket{
- // TODO loxi should set lengths automatically
- // last 4 is padding
- Len: 2 + 2 + 4 + 4 + length + 4, // length field + weight + watchPort + watchGroup + actions
Weight: uint16(bucket.Weight),
WatchPort: ofp.Port(bucket.WatchPort),
WatchGroup: bucket.WatchGroup,
@@ -141,16 +138,12 @@
return outBuckets
}
-func volthaActionsToOpenflow(actions []*openflow_13.OfpAction) ([]goloxi.IAction, uint16) {
+func volthaActionsToOpenflow(actions []*openflow_13.OfpAction) []goloxi.IAction {
outActions := make([]goloxi.IAction, len(actions))
- var length uint16
-
for i, action := range actions {
- a, l := parseAction(action)
- length += l
- outActions[i] = a
+ outActions[i] = parseAction(action)
}
- return outActions, length
+ return outActions
}
diff --git a/internal/pkg/openflow/meter.go b/internal/pkg/openflow/meter.go
index 574e505..a6411bb 100644
--- a/internal/pkg/openflow/meter.go
+++ b/internal/pkg/openflow/meter.go
@@ -18,7 +18,7 @@
import (
"encoding/json"
- ofp "github.com/donNewtonAlpha/goloxi/of13"
+ ofp "github.com/opencord/goloxi/of13"
"github.com/opencord/voltha-lib-go/v3/pkg/log"
"github.com/opencord/voltha-protos/v3/go/openflow_13"
"golang.org/x/net/context"
diff --git a/internal/pkg/openflow/packet.go b/internal/pkg/openflow/packet.go
index 7596d4a..9a13de2 100644
--- a/internal/pkg/openflow/packet.go
+++ b/internal/pkg/openflow/packet.go
@@ -18,7 +18,7 @@
import (
"encoding/json"
- ofp "github.com/donNewtonAlpha/goloxi/of13"
+ ofp "github.com/opencord/goloxi/of13"
"github.com/opencord/voltha-lib-go/v3/pkg/log"
"github.com/opencord/voltha-protos/v3/go/voltha"
)
diff --git a/internal/pkg/openflow/parseGrpcReturn.go b/internal/pkg/openflow/parseGrpcReturn.go
index beff0be..b9e4e29 100644
--- a/internal/pkg/openflow/parseGrpcReturn.go
+++ b/internal/pkg/openflow/parseGrpcReturn.go
@@ -19,14 +19,14 @@
"bytes"
"encoding/binary"
"encoding/json"
- "github.com/donNewtonAlpha/goloxi"
- ofp "github.com/donNewtonAlpha/goloxi/of13"
+ "github.com/opencord/goloxi"
+ ofp "github.com/opencord/goloxi/of13"
"github.com/opencord/voltha-lib-go/v3/pkg/log"
"github.com/opencord/voltha-protos/v3/go/openflow_13"
"github.com/opencord/voltha-protos/v3/go/voltha"
)
-func parseOxm(ofbField *openflow_13.OfpOxmOfbField) (goloxi.IOxm, uint16) {
+func parseOxm(ofbField *openflow_13.OfpOxmOfbField) goloxi.IOxm {
if logger.V(log.DebugLevel) {
js, _ := json.Marshal(ofbField)
logger.Debugw("parseOxm called",
@@ -38,22 +38,22 @@
ofpInPort := ofp.NewOxmInPort()
val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_Port)
ofpInPort.Value = ofp.Port(val.Port)
- return ofpInPort, 4
+ return ofpInPort
case voltha.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
ofpEthType := ofp.NewOxmEthType()
val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_EthType)
ofpEthType.Value = ofp.EthernetType(val.EthType)
- return ofpEthType, 2
+ return ofpEthType
case voltha.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
+ return ofpInPhyPort
case voltha.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
ofpIpProto := ofp.NewOxmIpProto()
val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_IpProto)
ofpIpProto.Value = ofp.IpPrototype(val.IpProto)
- return ofpIpProto, 1
+ return ofpIpProto
case voltha.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
ofpIpv4Dst := ofp.NewOxmIpv4Dst()
val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_Ipv4Dst)
@@ -64,23 +64,23 @@
log.Fields{"error": err})
}
ofpIpv4Dst.Value = buf.Bytes()
- return ofpIpv4Dst, 4
+ return ofpIpv4Dst
case voltha.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
ofpUdpSrc := ofp.NewOxmUdpSrc()
val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_UdpSrc)
ofpUdpSrc.Value = uint16(val.UdpSrc)
- return ofpUdpSrc, 2
+ return ofpUdpSrc
case voltha.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
ofpUdpDst := ofp.NewOxmUdpDst()
val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_UdpDst)
ofpUdpDst.Value = uint16(val.UdpDst)
- return ofpUdpDst, 2
+ return ofpUdpDst
case voltha.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
ofpVlanVid := ofp.NewOxmVlanVid()
val := ofbField.GetValue()
if val == nil {
ofpVlanVid.Value = uint16(0)
- return ofpVlanVid, 2
+ return ofpVlanVid
}
vlanId := val.(*openflow_13.OfpOxmOfbField_VlanVid)
if ofbField.HasMask {
@@ -95,15 +95,15 @@
ofpVlanVidMasked.ValueMask = uint16(vlanMask.VlanVidMask)
}
- return ofpVlanVidMasked, 4
+ return ofpVlanVidMasked
}
ofpVlanVid.Value = uint16(vlanId.VlanVid) | 0x1000
- return ofpVlanVid, 2
+ return ofpVlanVid
case voltha.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
ofpMetadata := ofp.NewOxmMetadata()
val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_TableMetadata)
ofpMetadata.Value = val.TableMetadata
- return ofpMetadata, 8
+ return ofpMetadata
default:
if logger.V(log.WarnLevel) {
js, _ := json.Marshal(ofbField)
@@ -111,10 +111,10 @@
log.Fields{"OfbField": js})
}
}
- return nil, 0
+ return nil
}
-func parseInstructions(ofpInstruction *openflow_13.OfpInstruction) (ofp.IInstruction, uint16) {
+func parseInstructions(ofpInstruction *openflow_13.OfpInstruction) ofp.IInstruction {
if logger.V(log.DebugLevel) {
js, _ := json.Marshal(ofpInstruction)
logger.Debugw("parseInstructions called",
@@ -125,50 +125,41 @@
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
+ return instruction
case ofp.OFPITMeter:
instruction := ofp.NewInstructionMeter()
- instruction.Len = 8
meter := data.(*openflow_13.OfpInstruction_Meter).Meter
instruction.MeterId = meter.MeterId
- return instruction, 8
+ return instruction
case ofp.OFPITGotoTable:
instruction := ofp.NewInstructionGotoTable()
- instruction.Len = 8
gotoTable := data.(*openflow_13.OfpInstruction_GotoTable).GotoTable
instruction.TableId = uint8(gotoTable.TableId)
- return instruction, 8
+ return instruction
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)
+ action := parseAction(ofpAction)
actions = append(actions, action)
- instructionSize += actionSize
-
}
instruction.Actions = actions
- instruction.SetLen(instructionSize)
if logger.V(log.DebugLevel) {
js, _ := json.Marshal(instruction)
logger.Debugw("parseInstructions returning",
log.Fields{
- "size": instructionSize,
"parsed-instruction": js})
}
- return instruction, instructionSize
+ return instruction
}
//shouldn't have reached here :<
- return nil, 0
+ return nil
}
-func parseAction(ofpAction *openflow_13.OfpAction) (goloxi.IAction, uint16) {
+func parseAction(ofpAction *openflow_13.OfpAction) goloxi.IAction {
if logger.V(log.DebugLevel) {
js, _ := json.Marshal(ofpAction)
logger.Debugw("parseAction called",
@@ -180,31 +171,26 @@
outputAction := ofp.NewActionOutput()
outputAction.Port = ofp.Port(ofpOutputAction.Port)
outputAction.MaxLen = uint16(ofpOutputAction.MaxLen)
- outputAction.Len = 16
- return outputAction, 16
+ return outputAction
case openflow_13.OfpActionType_OFPAT_PUSH_VLAN:
ofpPushVlanAction := ofp.NewActionPushVlan()
ofpPushVlanAction.Ethertype = uint16(ofpAction.GetPush().Ethertype)
- ofpPushVlanAction.Len = 8
- return ofpPushVlanAction, 8
+ return ofpPushVlanAction
case openflow_13.OfpActionType_OFPAT_POP_VLAN:
ofpPopVlanAction := ofp.NewActionPopVlan()
- ofpPopVlanAction.Len = 8
- return ofpPopVlanAction, 8
+ return ofpPopVlanAction
case openflow_13.OfpActionType_OFPAT_SET_FIELD:
ofpActionSetField := ofpAction.GetSetField()
setFieldAction := ofp.NewActionSetField()
- iOxm, _ := parseOxm(ofpActionSetField.GetField().GetOfbField())
+ iOxm := parseOxm(ofpActionSetField.GetField().GetOfbField())
setFieldAction.Field = iOxm
- setFieldAction.Len = 16
- return setFieldAction, 16
+ return setFieldAction
case openflow_13.OfpActionType_OFPAT_GROUP:
ofpGroupAction := ofpAction.GetGroup()
groupAction := ofp.NewActionGroup()
groupAction.GroupId = ofpGroupAction.GroupId
- groupAction.Len = 8
- return groupAction, 8
+ return groupAction
default:
if logger.V(log.WarnLevel) {
js, _ := json.Marshal(ofpAction)
@@ -212,7 +198,7 @@
log.Fields{"action": js})
}
}
- return nil, 0
+ return nil
}
func parsePortStats(port *voltha.LogicalPort) *ofp.PortStatsEntry {
diff --git a/internal/pkg/openflow/role.go b/internal/pkg/openflow/role.go
index 6d86fe9..1ea82c8 100644
--- a/internal/pkg/openflow/role.go
+++ b/internal/pkg/openflow/role.go
@@ -18,8 +18,8 @@
import (
"encoding/json"
- "github.com/donNewtonAlpha/goloxi"
- ofp "github.com/donNewtonAlpha/goloxi/of13"
+ "github.com/opencord/goloxi"
+ ofp "github.com/opencord/goloxi/of13"
"github.com/opencord/voltha-lib-go/v3/pkg/log"
)
diff --git a/internal/pkg/openflow/role_test.go b/internal/pkg/openflow/role_test.go
index 5eb3ba5..66a0387 100644
--- a/internal/pkg/openflow/role_test.go
+++ b/internal/pkg/openflow/role_test.go
@@ -17,7 +17,7 @@
package openflow
import (
- ofp "github.com/donNewtonAlpha/goloxi/of13"
+ ofp "github.com/opencord/goloxi/of13"
"github.com/stretchr/testify/assert"
"testing"
)
diff --git a/internal/pkg/openflow/setConfig.go b/internal/pkg/openflow/setConfig.go
index 64be03f..96d77ce 100644
--- a/internal/pkg/openflow/setConfig.go
+++ b/internal/pkg/openflow/setConfig.go
@@ -18,7 +18,7 @@
import (
"encoding/json"
- ofp "github.com/donNewtonAlpha/goloxi/of13"
+ ofp "github.com/opencord/goloxi/of13"
"github.com/opencord/voltha-lib-go/v3/pkg/log"
)
diff --git a/internal/pkg/openflow/stats.go b/internal/pkg/openflow/stats.go
index 9b642ce..8330d10 100644
--- a/internal/pkg/openflow/stats.go
+++ b/internal/pkg/openflow/stats.go
@@ -19,14 +19,12 @@
import (
"context"
"encoding/json"
- "net"
- "unsafe"
-
- "github.com/donNewtonAlpha/goloxi"
- ofp "github.com/donNewtonAlpha/goloxi/of13"
+ "github.com/opencord/goloxi"
+ ofp "github.com/opencord/goloxi/of13"
"github.com/opencord/voltha-lib-go/v3/pkg/log"
"github.com/opencord/voltha-protos/v3/go/common"
"github.com/opencord/voltha-protos/v3/go/openflow_13"
+ "net"
)
func (ofc *OFConnection) handleStatsRequest(request ofp.IHeader, statType uint16) error {
@@ -62,7 +60,6 @@
if err != nil {
return err
}
- response.Length = uint16(unsafe.Sizeof(*response))
if logger.V(log.DebugLevel) {
reqJs, _ := json.Marshal(statsReq)
resJs, _ := json.Marshal(response)
@@ -341,39 +338,25 @@
entry.SetCookie(item.GetCookie())
entry.SetPacketCount(item.GetPacketCount())
entry.SetByteCount(item.GetByteCount())
- entrySize := uint16(48)
match := ofp.NewMatchV3()
pbMatch := item.GetMatch()
match.SetType(uint16(pbMatch.GetType()))
- size := uint16(4)
var fields []goloxi.IOxm
for _, oxmField := range pbMatch.GetOxmFields() {
field := oxmField.GetField()
ofbField := field.(*openflow_13.OfpOxmField_OfbField).OfbField
- iOxm, oxmSize := parseOxm(ofbField)
+ iOxm := parseOxm(ofbField)
fields = append(fields, iOxm)
- if oxmSize > 0 {
- size += 4 //header for oxm
- }
- size += oxmSize
}
match.OxmList = fields
- match.Length = uint16(size)
- //account for 8 byte alignment
- if size%8 != 0 {
- size = ((size / 8) + 1) * 8
- }
- entrySize += size
entry.SetMatch(*match)
var instructions []ofp.IInstruction
for _, ofpInstruction := range item.Instructions {
- instruction, size := parseInstructions(ofpInstruction)
+ instruction := parseInstructions(ofpInstruction)
instructions = append(instructions, instruction)
- entrySize += size
}
entry.Instructions = instructions
- entry.Length = entrySize
flow = append(flow, entry)
}
response.SetEntries(flow)
@@ -426,10 +409,6 @@
bucketStatsList = append(bucketStatsList, &bucketCounter)
}
entry.SetBucketStats(bucketStatsList)
- // TODO loxi should set lengths automatically
- // last 2 + 4 are padding
- length := 2 + 4 + 4 + 8 + 8 + 4 + 4 + len(bucketStatsList)*16 + 2 + 4
- entry.SetLength(uint16(length))
groupStatsEntries = append(groupStatsEntries, &entry)
}
response.SetEntries(groupStatsEntries)
@@ -455,15 +434,8 @@
desc := item.GetDesc()
buckets := volthaBucketsToOpenflow(desc.Buckets)
- var bucketsLength uint16
- for _, b := range buckets {
- bucketsLength += b.Len
- }
groupDesc := &ofp.GroupDescStatsEntry{
- // TODO loxi should set lengths automatically
- // last 1 is padding
- Length: 2 + 1 + 4 + bucketsLength + 1, // length field + groupType + groupId + buckets
GroupType: volthaGroupTypeToOpenflow(desc.Type),
GroupId: desc.GroupId,
Buckets: buckets,
@@ -497,10 +469,8 @@
if err != nil {
return nil, err
}
- size := uint16(5) // size of stats header
var meterStats []*ofp.MeterStats
for _, item := range resp.Items {
- entrySize := uint16(40) // size of entry header
meterStat := ofp.NewMeterStats()
stats := item.Stats
meterStat.DurationNsec = stats.DurationNsec
@@ -514,15 +484,11 @@
bandStat.ByteBandCount = bStat.ByteBandCount
bandStat.PacketBandCount = bStat.PacketBandCount
bandStats = append(bandStats, bandStat)
- entrySize += uint16(16) // size of each band stat
}
meterStat.SetBandStats(bandStats)
- meterStat.Len = entrySize
meterStats = append(meterStats, meterStat)
- size += entrySize
}
response.SetEntries(meterStats)
- response.SetLength(size)
return response, nil
}
diff --git a/internal/pkg/openflow/utils.go b/internal/pkg/openflow/utils.go
index dac2f22..8745087 100644
--- a/internal/pkg/openflow/utils.go
+++ b/internal/pkg/openflow/utils.go
@@ -18,7 +18,7 @@
import (
"fmt"
- ofp "github.com/donNewtonAlpha/goloxi/of13"
+ ofp "github.com/opencord/goloxi/of13"
"github.com/opencord/voltha-protos/v3/go/openflow_13"
"strings"
"sync"