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 24f4364
Show file tree
Hide file tree
Showing 20 changed files with 167 additions and 79 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
10 changes: 8 additions & 2 deletions pkg/agent/controller/networkpolicy/fqdn.go
Original file line number Diff line number Diff line change
Expand Up @@ -755,7 +755,10 @@ func (f *fqdnController) handlePacketIn(pktIn *ofctrl.PacketIn) error {
f.onDNSResponseMsg(&dnsMsg, time.Now(), waitCh)
}
go func() {
ethernetPkt := pktIn.Data.(*protocol.Ethernet)
ethernetPkt, err := getEthernetPacket(pktIn)
if err != nil {
return
}
switch ipPkt := ethernetPkt.Data.(type) {
case *protocol.IPv4:
switch dnsPkt := ipPkt.Data.(type) {
Expand Down Expand Up @@ -789,7 +792,10 @@ func (f *fqdnController) sendDNSPacketout(pktIn *ofctrl.PacketIn) error {
prot uint8
isIPv6 bool
)
ethernetPkt := pktIn.Data.(*protocol.Ethernet)
ethernetPkt, err := getEthernetPacket(pktIn)
if err != nil {
return err
}
switch ipPkt := ethernetPkt.Data.(type) {
case *protocol.IPv4:
srcIP = ipPkt.NWSrc.String()
Expand Down
13 changes: 12 additions & 1 deletion pkg/agent/controller/networkpolicy/packetin.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"time"

"antrea.io/libOpenflow/openflow15"
"antrea.io/libOpenflow/protocol"
"antrea.io/libOpenflow/util"
"antrea.io/ofnet/ofctrl"
"github.com/vmware/go-ipfix/pkg/registry"
"k8s.io/klog/v2"
Expand Down Expand Up @@ -69,7 +71,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 Expand Up @@ -209,3 +211,12 @@ func isAntreaPolicyEgressTable(tableID uint8) bool {
}
return false
}

func getEthernetPacket(pktIn *ofctrl.PacketIn) (*protocol.Ethernet, error) {
ethernetPkt := new(protocol.Ethernet)
if err := ethernetPkt.UnmarshalBinary(pktIn.Data.(*util.Buffer).Bytes()); err != nil {
klog.ErrorS(err, "Failed to parse ethernet packet from packet-in message")
return nil, err
}
return ethernetPkt, nil
}
10 changes: 6 additions & 4 deletions pkg/agent/controller/networkpolicy/reject.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,12 @@ import (
"encoding/binary"
"fmt"

"antrea.io/libOpenflow/protocol"
"antrea.io/ofnet/ofctrl"

"antrea.io/antrea/pkg/agent/config"
"antrea.io/antrea/pkg/agent/interfacestore"
"antrea.io/antrea/pkg/agent/openflow"
binding "antrea.io/antrea/pkg/ovs/openflow"
"antrea.io/libOpenflow/protocol"
"antrea.io/ofnet/ofctrl"
)

const (
Expand Down Expand Up @@ -83,7 +82,10 @@ const (
// packet-in message.
func (c *Controller) rejectRequest(pktIn *ofctrl.PacketIn) error {
// Get ethernet data.
ethernetPkt := pktIn.Data.(*protocol.Ethernet)
ethernetPkt, err := getEthernetPacket(pktIn)
if err != nil {
return err
}
srcMAC := ethernetPkt.HWDst.String()
dstMAC := ethernetPkt.HWSrc.String()

Expand Down
8 changes: 5 additions & 3 deletions pkg/agent/controller/traceflow/packetin.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (

"antrea.io/libOpenflow/openflow15"
"antrea.io/libOpenflow/protocol"
"antrea.io/libOpenflow/util"
"antrea.io/ofnet/ofctrl"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/util/retry"
Expand Down Expand Up @@ -78,8 +79,9 @@ func (c *Controller) parsePacketIn(pktIn *ofctrl.PacketIn) (*crdv1alpha1.Tracefl
var err error
var tag uint8
var ctNwDst, ctNwSrc, ipDst, ipSrc string
etherData, ok := pktIn.Data.(*protocol.Ethernet)
if ok {
etherData := new(protocol.Ethernet)
if err := etherData.UnmarshalBinary(pktIn.Data.(*util.Buffer).Bytes()); err != nil {
klog.ErrorS(err, "Failed to parse ethernet packet from packet-in message")
return nil, nil, nil, fmt.Errorf("failed to parse packet data")
}
if etherData.Ethertype == protocol.IPv4_MSG {
Expand Down Expand Up @@ -277,7 +279,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: 3 additions & 1 deletion pkg/agent/controller/traceflow/packetin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,9 @@ func TestParseCapturedPacket(t *testing.T) {
if tt.isIPv6 {
ethType = uint16(protocol.IPv6_MSG)
}
pktIn := ofctrl.PacketIn{Data: &protocol.Ethernet{Ethertype: ethType, Data: tt.pktInData}}
etherPkt := protocol.Ethernet{Ethertype: ethType, Data: tt.pktInData}
pktBytes, _ := etherPkt.MarshalBinary()
pktIn := ofctrl.PacketIn{Data: util.NewBuffer(pktBytes)}
packet := parseCapturedPacket(&pktIn)
assert.True(t, reflect.DeepEqual(packet, tt.pktCap), "parsed packet does not match the expected")
})
Expand Down
4 changes: 3 additions & 1 deletion pkg/agent/multicast/mcast_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -402,12 +402,14 @@ func createIGMPReportPacketIn(joinedGroups []net.IP, leftGroups []net.IP, versio
Length: 20 + m.Len(),
Data: m,
}
pkt.Data = &protocol.Ethernet{
ethernetPkt := protocol.Ethernet{
HWDst: pktInDstMAC,
HWSrc: pktInSrcMAC,
Ethertype: protocol.IPv4_MSG,
Data: ipPacket,
}
pktBytes, _ := ethernetPkt.MarshalBinary()
pkt.Data = util.NewBuffer(pktBytes)
return ofctrl.PacketIn(*pkt)
}
pkts := make([]*ofctrl.PacketIn, 0)
Expand Down
10 changes: 7 additions & 3 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 Expand Up @@ -122,7 +122,11 @@ func (s *IGMPSnooper) processPacketIn(pktIn *ofctrl.PacketIn) error {
if iface.Type == interfacestore.ContainerInterface {
podName = iface.PodName
}
pktData := pktIn.Data.(*protocol.Ethernet)
pktData := new(protocol.Ethernet)
if err := pktData.UnmarshalBinary(pktIn.Data.(*util.Buffer).Bytes()); err != nil {
klog.ErrorS(err, "Failed to parse ethernet packet from packet-in message")
return err
}
igmp, err := parseIGMPPacket(*pktData)
if err != nil {
return err
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)}
}
4 changes: 0 additions & 4 deletions pkg/agent/openflow/pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -349,10 +349,6 @@ var DispositionToString = map[uint32]string{
}

var (
// traceflowTagToSRange stores Traceflow dataplane tag to DSCP bits of
// IP header ToS field.
traceflowTagToSRange = binding.IPDSCPToSRange

// snatPktMarkRange takes an 8-bit range of pkt_mark to store the ID of
// a SNAT IP. The bit range must match SNATIPMarkMask.
snatPktMarkRange = &binding.Range{0, 7}
Expand Down
33 changes: 12 additions & 21 deletions pkg/ovs/openflow/ofctrl_action.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ func (a *ofCTAction) LoadToLabelField(value uint64, labelField *CtLabel) CTActio
if labelField.rng != nil {
mask := ^uint64(0) >> (64 - labelField.rng.Length()) << labelField.rng.Offset()
valueData = valueData << (labelField.rng.Offset() % 64)
if labelField.rng.Offset() < 64 {
if labelField.rng.Offset() > 64 {
binary.BigEndian.PutUint64(maskBytes[0:8], mask)
binary.BigEndian.PutUint64(labelBytes[0:8], valueData)
} else {
Expand All @@ -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
10 changes: 6 additions & 4 deletions pkg/ovs/openflow/ofctrl_packetin.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,11 @@
package openflow

import (
"encoding/binary"
"errors"

"antrea.io/libOpenflow/protocol"
"antrea.io/libOpenflow/util"
"antrea.io/ofnet/ofctrl"
"encoding/binary"
"errors"
)

const (
Expand Down Expand Up @@ -83,7 +82,10 @@ func getICMPHeaderData(ipPkt util.Message) (icmpType, icmpCode uint8, icmpEchoID

func ParsePacketIn(pktIn *ofctrl.PacketIn) (*Packet, error) {
packet := Packet{}
ethernetData := pktIn.Data.(*protocol.Ethernet)
ethernetData := new(protocol.Ethernet)
if err := ethernetData.UnmarshalBinary(pktIn.Data.(*util.Buffer).Bytes()); err != nil {
return nil, err
}
packet.DestinationMAC = ethernetData.HWDst
packet.SourceMAC = ethernetData.HWSrc

Expand Down
Loading

0 comments on commit 24f4364

Please sign in to comment.