Skip to content

Commit

Permalink
consume openflow15.FindOxmIdByName to get OxmId
Browse files Browse the repository at this point in the history
1. consume openflow15.FindOxmIdByName to get OxmId
2. enhance packet-in parser to support get register match in the
   message, as xreg is used in OF1.5
  • Loading branch information
wenyingd committed May 25, 2022
1 parent ed1969a commit 693b0bd
Show file tree
Hide file tree
Showing 13 changed files with 105 additions and 46 deletions.
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ require (
// Newer version of github.com/googleapis/gnostic make use of newer gopkg.in/yaml(v3), which conflicts with
// explicit imports of gopkg.in/yaml.v2.
replace (
antrea.io/libOpenflow v0.6.2 => github.com/ashish-varma/libOpenflow v0.5.3-0.20220511235544-ed029320dc7f
antrea.io/ofnet v0.5.7 => github.com/ashish-varma/ofnet v0.2.5-0.20220511051314-4f8eeb7570f6
antrea.io/libOpenflow v0.6.2 => github.com/ashish-varma/libOpenflow v0.5.3-0.20220525043953-5dc6e2381af9
antrea.io/ofnet v0.5.7 => github.com/ashish-varma/ofnet v0.2.5-0.20220524015622-c8b1f7c848ed
github.com/googleapis/gnostic v0.5.5 => github.com/googleapis/gnostic v0.4.1
)
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,10 @@ github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmV
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/ashish-varma/libOpenflow v0.5.3-0.20220511235544-ed029320dc7f h1:gYWmQCsu8g7tDP9FR1UsadS+0iuVizEuSgwz2OJiF60=
github.com/ashish-varma/libOpenflow v0.5.3-0.20220511235544-ed029320dc7f/go.mod h1:CzEJZxDNAupiGxeL5VOw92PsxfyvehEAvE3PiC6gr8o=
github.com/ashish-varma/ofnet v0.2.5-0.20220511051314-4f8eeb7570f6 h1:E4wWdXZR+dG0nuqGmXQfbGIu+6zG/2/wc0vD9gV6PU4=
github.com/ashish-varma/ofnet v0.2.5-0.20220511051314-4f8eeb7570f6/go.mod h1:8TJVF6MLe9/gZ/KbhGUvULs9/TxssepEaYEe+o1SEgs=
github.com/ashish-varma/libOpenflow v0.5.3-0.20220525043953-5dc6e2381af9 h1:L7ahmHdnHhtCWzJJV32rFX20wp1hv6+QyHrP4j48LZw=
github.com/ashish-varma/libOpenflow v0.5.3-0.20220525043953-5dc6e2381af9/go.mod h1:CzEJZxDNAupiGxeL5VOw92PsxfyvehEAvE3PiC6gr8o=
github.com/ashish-varma/ofnet v0.2.5-0.20220524015622-c8b1f7c848ed h1:aeFqTzMUQEjHtvSR9rsoNEEdGjxSKH1fMT1KN6iyq9w=
github.com/ashish-varma/ofnet v0.2.5-0.20220524015622-c8b1f7c848ed/go.mod h1:8TJVF6MLe9/gZ/KbhGUvULs9/TxssepEaYEe+o1SEgs=
github.com/awalterschulze/gographviz v2.0.1+incompatible h1:XIECBRq9VPEQqkQL5pw2OtjCAdrtIgFKoJU8eT98AS8=
github.com/awalterschulze/gographviz v2.0.1+incompatible/go.mod h1:GEV5wmg4YquNw7v1kkyoX9etIk8yVmXj+AkDHuuETHs=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
Expand Down
2 changes: 1 addition & 1 deletion pkg/agent/controller/networkpolicy/packetin.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func (c *Controller) HandlePacketIn(pktIn *ofctrl.PacketIn) error {

// getMatchRegField returns match to the regNum register.
func getMatchRegField(matchers *ofctrl.Matchers, field *binding.RegField) *ofctrl.MatchField {
return matchers.GetMatchByName(field.GetNXFieldName())
return openflow.GetRegMatchInPacketIn(matchers, field.GetRegID())
}

// getMatch receives ofctrl matchers and table id, match field.
Expand Down
2 changes: 1 addition & 1 deletion pkg/agent/controller/traceflow/packetin.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ func (c *Controller) parsePacketIn(pktIn *ofctrl.PacketIn) (*crdv1alpha1.Tracefl
}

func getMatchRegField(matchers *ofctrl.Matchers, field *binding.RegField) *ofctrl.MatchField {
return matchers.GetMatchByName(field.GetNXFieldName())
return openflow.GetRegMatchInPacketIn(matchers, field.GetRegID())
}

func getMatchTunnelDstField(matchers *ofctrl.Matchers, isIPv6 bool) *ofctrl.MatchField {
Expand Down
4 changes: 2 additions & 2 deletions pkg/agent/multicast/mcast_discovery.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ type IGMPSnooper struct {
}

func (s *IGMPSnooper) HandlePacketIn(pktIn *ofctrl.PacketIn) error {
matches := pktIn.GetMatches()
matchers := pktIn.GetMatches()
// Get custom reasons in this packet-in.
match := matches.GetMatchByName(openflow.CustomReasonField.GetNXFieldName())
match := openflow.GetRegMatchInPacketIn(matchers, openflow.CustomReasonField.GetRegID())
customReasons, err := getInfoInReg(match, openflow.CustomReasonField.GetRange().ToNXRange())
if err != nil {
klog.ErrorS(err, "Received error while unloading customReason from OVS reg", "regField", openflow.CustomReasonField.GetName())
Expand Down
19 changes: 19 additions & 0 deletions pkg/agent/openflow/packetin.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
package openflow

import (
"encoding/binary"
"fmt"

"antrea.io/libOpenflow/openflow15"
"antrea.io/ofnet/ofctrl"
"golang.org/x/time/rate"
"k8s.io/klog/v2"
Expand Down Expand Up @@ -124,3 +126,20 @@ func (c *client) parsePacketIn(featurePacketIn *featureStartPacketIn) {
}
}
}

func GetRegMatchInPacketIn(matchers *ofctrl.Matchers, regID int) *ofctrl.MatchField {
xregID := uint8(regID / 2)
startBit := 4 * (regID % 2)
f := matchers.GetMatch(openflow15.OXM_CLASS_PACKET_REGS, xregID)
if f == nil {
return nil
}
dataBytes := f.Value.(*openflow15.ByteArrayField).Data
data := binary.BigEndian.Uint32(dataBytes[startBit : startBit+4])
var mask uint32
if f.HasMask {
maskBytes, _ := f.Mask.MarshalBinary()
mask = binary.BigEndian.Uint32(maskBytes[startBit : startBit+4])
}
return &ofctrl.MatchField{MatchField: openflow15.NewRegMatchFieldWithMask(regID, data, mask)}
}
31 changes: 11 additions & 20 deletions pkg/ovs/openflow/ofctrl_action.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,16 +136,16 @@ func (a *ofCTAction) LoadToLabelField(value uint64, labelField *CtLabel) CTActio

// MoveToLabel is an action to move data into ct_label.
func (a *ofCTAction) MoveToLabel(fromName string, fromRng, labelRng *Range) CTAction {
fromField := getOxmIdByFieldName(fromName)
toField := getOxmIdByFieldName(NxmFieldCtLabel)
fromField, _ := openflow15.FindOxmIdByName(fromName, false)
toField, _ := openflow15.FindOxmIdByName(NxmFieldCtLabel, false)
a.move(fromField, toField, uint16(fromRng.Length()), uint16(fromRng[0]), uint16(labelRng[0]))
return a
}

// MoveToCtMarkField is an action to move data into ct_mark.
func (a *ofCTAction) MoveToCtMarkField(fromRegField *RegField, ctMarkField *CtMarkField) CTAction {
fromField := getOxmIdByFieldName(fromRegField.GetNXFieldName())
toField := getOxmIdByFieldName(NxmFieldCtMark)
fromField, _ := openflow15.FindOxmIdByName(fromRegField.GetNXFieldName(), false)
toField, _ := openflow15.FindOxmIdByName(NxmFieldCtMark, false)
a.move(fromField, toField, uint16(fromRegField.GetRange().Length()), uint16(fromRegField.GetRange()[0]), uint16(ctMarkField.rng[0]))
return a
}
Expand Down Expand Up @@ -356,12 +356,8 @@ func (a *ofFlowAction) LoadPktMarkRange(value uint32, rng *Range) FlowBuilder {

// LoadIPDSCP is an action to load data to IP DSCP bits.
func (a *ofFlowAction) LoadIPDSCP(value uint8) FlowBuilder {
ipDscpField := openflow15.NewIpDscpField(value << IPDSCPToSRange.Offset())
ipDscpField.HasMask = true
ipDscpMask := &openflow15.IpDscpField{Dscp: uint8(0xff) >> (8 - IPDSCPToSRange.Length()) << IPDSCPToSRange.Offset()}
ipDscpField.Mask = ipDscpMask
ipDscpField.Length = 2

mask := uint8(0xff) >> (8 - IPDSCPToSRange.Length()) << IPDSCPToSRange.Offset()
ipDscpField := openflow15.NewIpDscpField(value<<IPDSCPToSRange.Offset(), &mask)
return a.setField(ipDscpField)
}

Expand Down Expand Up @@ -396,8 +392,8 @@ func (a *ofFlowAction) Move(fromField, toField string) FlowBuilder {

// MoveRange is an action to move data from "fromField" at "fromRange" to "toField" at "toRange".
func (a *ofFlowAction) MoveRange(fromField, toField string, fromRange, toRange Range) FlowBuilder {
srcOxmId := getOxmIdByFieldName(fromField)
dstOxmId := getOxmIdByFieldName(toField)
srcOxmId, _ := openflow15.FindOxmIdByName(fromField, false)
dstOxmId, _ := openflow15.FindOxmIdByName(toField, false)
return a.copyField(srcOxmId, dstOxmId, fromRange, toRange)
}

Expand All @@ -411,13 +407,13 @@ func (a *ofFlowAction) copyField(srcOxmId, dstOxmId *openflow15.OxmId, fromRange
}

func (a *ofFlowAction) MoveToTunMetadata(fromField string, toTunMetadataId int, fromRange, toRange Range, tlvLength uint8) FlowBuilder {
srcOxmId := getOxmIdByFieldName(fromField)
srcOxmId, _ := openflow15.FindOxmIdByName(fromField, false)
dstOxmId := getTunMetadataOxmId(toTunMetadataId, tlvLength)
return a.copyField(srcOxmId, dstOxmId, fromRange, toRange)
}

func (a *ofFlowAction) MoveFromTunMetadata(fromTunMetadataId int, toField string, fromRange, toRange Range, tlvLength uint8) FlowBuilder {
dstOxmId := getOxmIdByFieldName(toField)
dstOxmId, _ := openflow15.FindOxmIdByName(toField, false)
srcOxmId := getTunMetadataOxmId(fromTunMetadataId, tlvLength)
return a.copyField(srcOxmId, dstOxmId, fromRange, toRange)
}
Expand Down Expand Up @@ -718,14 +714,9 @@ func (a *ofFlowAction) GotoStage(stage StageID) FlowBuilder {
return a.builder
}

func getOxmIdByFieldName(fieldName string) *openflow15.OxmId {
field, _ := openflow15.FindFieldHeaderByName(fieldName, false)
return openflow15.NewOxmId(field.Class, field.Field, field.HasMask, field.Length, field.ExperimenterID)
}

func getTunMetadataOxmId(id int, tlvLength uint8) *openflow15.OxmId {
field := fmt.Sprintf("%s%d", NxmFieldTunMetadata, id)
oxmId := getOxmIdByFieldName(field)
oxmId, _ := openflow15.FindOxmIdByName(field, false)
oxmId.Length = tlvLength
return oxmId
}
16 changes: 8 additions & 8 deletions pkg/ovs/openflow/ofctrl_bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,8 @@ type OFBridge struct {
// connected is an internal channel to notify if connected to the OFSwitch or not. It is used only in Connect method.
connected chan bool
// pktConsumers is a map from PacketIn reason to the channel that is used to publish the PacketIn message.
pktConsumers sync.Map
multipartReplyChs map[uint32]chan *openflow15.MultipartReply
pktConsumers sync.Map
multipartReplyChs map[uint32]chan *openflow15.MultipartReply
tunMetadataLengthMap map[uint16]uint8
}

Expand Down Expand Up @@ -755,12 +755,12 @@ func (b *OFBridge) processTableFeatures(ch chan *openflow15.MultipartReply) {

func NewOFBridge(br string, mgmtAddr string) Bridge {
s := &OFBridge{
bridgeName: br,
mgmtAddr: mgmtAddr,
tableCache: make(map[uint8]*ofTable),
retryInterval: 1 * time.Second,
pktConsumers: sync.Map{},
multipartReplyChs: make(map[uint32]chan *openflow15.MultipartReply),
bridgeName: br,
mgmtAddr: mgmtAddr,
tableCache: make(map[uint8]*ofTable),
retryInterval: 1 * time.Second,
pktConsumers: sync.Map{},
multipartReplyChs: make(map[uint32]chan *openflow15.MultipartReply),
tunMetadataLengthMap: make(map[uint16]uint8),
}
s.controller = ofctrl.NewController(s)
Expand Down
3 changes: 3 additions & 0 deletions pkg/ovs/openflow/ofctrl_packetout.go
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,9 @@ func (b *ofPacketOutBuilder) Done() *ofctrl.PacketOut {
klog.Errorf("Invalid PacketOutBuilder: IP header and IPv6 header are not allowed to exist at the same time")
return nil
}
if b.pktOut.InPort == 0 {
b.pktOut.InPort = openflow15.P_CONTROLLER
}
if b.pktOut.IPv6Header == nil {
if b.pktOut.ICMPHeader != nil {
if len(b.pktOut.ICMPHeader.Data) == 0 {
Expand Down
8 changes: 6 additions & 2 deletions pkg/ovs/openflow/ofctrl_packetout_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"reflect"
"testing"

"antrea.io/libOpenflow/openflow15"
"antrea.io/libOpenflow/protocol"
"antrea.io/ofnet/ofctrl"
)
Expand Down Expand Up @@ -782,6 +783,9 @@ func Test_ofPacketOutBuilder_Done(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.want != nil && tt.want.InPort == 0 {
tt.want.InPort = openflow15.P_CONTROLLER
}
b := &ofPacketOutBuilder{
pktOut: tt.fields.pktOut,
icmpID: tt.fields.icmpID,
Expand All @@ -805,7 +809,7 @@ func Test_ofPacketOutBuilder_Done(t *testing.T) {
t.Errorf("Done() = %v, want %v", got.ICMPHeader, tt.want.ICMPHeader)
}
if !reflect.DeepEqual(got.TCPHeader, tt.want.TCPHeader) {
t.Errorf("Done() = %v, want %v", got.TCPHeader, tt.want.TCPHeader)
t.Errorf("Done() = %+v, want %+v", got.TCPHeader, tt.want.TCPHeader)
}
if !reflect.DeepEqual(got.UDPHeader, tt.want.UDPHeader) {
t.Errorf("Done() = %v, want %v", got.UDPHeader, tt.want.UDPHeader)
Expand All @@ -817,7 +821,7 @@ func Test_ofPacketOutBuilder_Done(t *testing.T) {
t.Errorf("Done() = %v, want %v", got.IPv6Header, tt.want.IPv6Header)
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("Done() = %v, want %v", got, tt.want)
t.Errorf("Done() = %+v, want %+v", got, tt.want)
}
})
}
Expand Down
42 changes: 42 additions & 0 deletions pkg/ovs/openflow/testing/mock_openflow.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions test/integration/agent/openflow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,7 @@ func expectedProxyServiceGroupAndFlows(gid uint32, svc svcConfig, endpointList [
svcFlows := expectTableFlows{tableName: "ServiceLB", flows: []*ofTestUtils.ExpectFlow{
{
MatchStr: fmt.Sprintf("priority=200,%s,reg4=0x10000/0x70000,nw_dst=%s,tp_dst=%d", string(svc.protocol), svc.ip.String(), svc.port),
ActStr: fmt.Sprintf("set_field:0x%x/0x70000->reg4,set_field:0x200/0x200->reg0,set_field:0x%x->reg7,group:%d", serviceLearnReg << 16, gid, gid),
ActStr: fmt.Sprintf("set_field:0x%x/0x70000->reg4,set_field:0x200/0x200->reg0,set_field:0x%x->reg7,group:%d", serviceLearnReg<<16, gid, gid),
},
{
MatchStr: fmt.Sprintf("priority=190,%s,reg4=0x30000/0x70000,nw_dst=%s,tp_dst=%d", string(svc.protocol), svc.ip.String(), svc.port),
Expand Down Expand Up @@ -859,9 +859,8 @@ func checkConjunctionFlows(t *testing.T, ruleTable string, priority int, ruleID
nextTable = ofClient.EgressMetricTable.GetName()
}

flow := &ofTestUtils.ExpectFlow{MatchStr: conjunctionActionMatch, ActStr: fmt.Sprintf("set_field:0x%x->reg%d,ct(commit,table=%s,zone=65520,exec(load:0x%x->NXM_NX_CT_LABEL[0..31])", ruleID, conjReg, nextTable, ruleID)}
flow := &ofTestUtils.ExpectFlow{MatchStr: conjunctionActionMatch, ActStr: fmt.Sprintf("set_field:0x%x->reg%d,ct(commit,table=%s,zone=65520,exec(set_field:0x%x0000000000000000/0xffffffff0000000000000000->ct_label)", ruleID, conjReg, nextTable, ruleID)}
testFunc(t, ofTestUtils.OfctlFlowMatch(flowList, ruleTable, flow), "Failed to update conjunction action flow")

useIPv4 := false
useIPv6 := false

Expand Down
7 changes: 4 additions & 3 deletions test/integration/ovs/ofctrl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"golang.org/x/time/rate"
"k8s.io/apimachinery/pkg/util/wait"

"antrea.io/antrea/pkg/agent/openflow"
binding "antrea.io/antrea/pkg/ovs/openflow"
"antrea.io/antrea/pkg/ovs/ovsconfig"
"antrea.io/antrea/pkg/ovs/ovsctl"
Expand Down Expand Up @@ -627,15 +628,15 @@ func TestPacketOutIn(t *testing.T) {
pktIn := pktInQueue.GetRateLimited(make(chan struct{}))
matchers := pktIn.GetMatches()

reg2Match := matchers.GetMatchByName("NXM_NX_REG2")
reg2Match := openflow.GetRegMatchInPacketIn(matchers, 2)
assert.NotNil(t, reg2Match)
reg2Value := reg2Match.GetValue()
assert.NotNil(t, reg2Value)
value2, ok2 := reg2Value.(*ofctrl.NXRegister)
assert.True(t, ok2)
assert.Equal(t, reg2Data, ofctrl.GetUint32ValueWithRange(value2.Data, reg2Field.GetRange().ToNXRange()))

reg3Match := matchers.GetMatchByName("NXM_NX_REG3")
reg3Match := openflow.GetRegMatchInPacketIn(matchers, 3)
assert.NotNil(t, reg3Match)
reg3Value := reg3Match.GetValue()
assert.NotNil(t, reg3Value)
Expand Down Expand Up @@ -1040,7 +1041,7 @@ func prepareFlows(table binding.Table) ([]binding.Flow, []*ExpectFlow) {
&ExpectFlow{"priority=200,ip,in_port=3,dl_src=aa:aa:aa:aa:aa:13,nw_src=192.168.1.3", gotoTableAction},
&ExpectFlow{"priority=200,arp,arp_tpa=192.168.2.1,arp_op=1", "move:NXM_OF_ETH_SRC[]->NXM_OF_ETH_DST[],set_field:aa:bb:cc:dd:ee:ff->eth_src,set_field:2->arp_op,move:NXM_NX_ARP_SHA[]->NXM_NX_ARP_THA[],set_field:aa:bb:cc:dd:ee:ff->arp_sha,move:NXM_OF_ARP_SPA[]->NXM_OF_ARP_TPA[],set_field:192.168.2.1->arp_spa,IN_PORT"},
&ExpectFlow{"priority=190,arp", "NORMAL"},
&ExpectFlow{"priority=200,tcp", fmt.Sprintf("learn(table=%d,idle_timeout=10,priority=190,delete_learned,cookie=0x1,eth_type=0x800,nw_proto=6,NXM_OF_TCP_DST[],NXM_NX_REG0[0..15]=0xfff,load:NXM_NX_REG0[0..15]->NXM_NX_REG0[0..15],set_field:0xffe0000/0xffff00000->reg0),goto_table:%d", table.GetID(), table.GetNext())},
&ExpectFlow{"priority=200,tcp", fmt.Sprintf("learn(table=%d,idle_timeout=10,priority=190,delete_learned,cookie=0x1,eth_type=0x800,nw_proto=6,NXM_OF_TCP_DST[],NXM_NX_REG0[0..15]=0xfff,load:NXM_NX_REG0[0..15]->NXM_NX_REG0[0..15],load:0xffe->NXM_NX_REG0[16..31]),goto_table:%d", table.GetID(), table.GetNext())},
&ExpectFlow{"priority=200,ip", fmt.Sprintf("ct(table=%d,zone=65520)", table.GetNext())},
&ExpectFlow{"priority=210,ct_state=-new+trk,ct_mark=0x2/0x2,ip,reg0=0x1/0xffff", gotoTableAction},
&ExpectFlow{"priority=200,ct_state=+new+trk,ip,reg0=0x1/0xffff", fmt.Sprintf("ct(commit,table=%d,zone=65520,exec(set_field:0x2/0x2->ct_mark)", table.GetNext())},
Expand Down

0 comments on commit 693b0bd

Please sign in to comment.