diff --git a/go.mod b/go.mod index 1b27c67992b..f0bea8282fe 100644 --- a/go.mod +++ b/go.mod @@ -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 ) diff --git a/go.sum b/go.sum index 717f9c0be9b..e99bfb04e44 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/pkg/agent/controller/networkpolicy/fqdn.go b/pkg/agent/controller/networkpolicy/fqdn.go index c47d5bb6c30..35b47067182 100644 --- a/pkg/agent/controller/networkpolicy/fqdn.go +++ b/pkg/agent/controller/networkpolicy/fqdn.go @@ -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) { @@ -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() diff --git a/pkg/agent/controller/networkpolicy/packetin.go b/pkg/agent/controller/networkpolicy/packetin.go index 85291307e88..6df33027d72 100644 --- a/pkg/agent/controller/networkpolicy/packetin.go +++ b/pkg/agent/controller/networkpolicy/packetin.go @@ -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" @@ -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. @@ -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 +} diff --git a/pkg/agent/controller/networkpolicy/reject.go b/pkg/agent/controller/networkpolicy/reject.go index 2bfeaa4fb55..861d4e03102 100644 --- a/pkg/agent/controller/networkpolicy/reject.go +++ b/pkg/agent/controller/networkpolicy/reject.go @@ -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 ( @@ -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() diff --git a/pkg/agent/controller/traceflow/packetin.go b/pkg/agent/controller/traceflow/packetin.go index 5c5131fd615..7273d56ed32 100644 --- a/pkg/agent/controller/traceflow/packetin.go +++ b/pkg/agent/controller/traceflow/packetin.go @@ -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" @@ -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 { @@ -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 { diff --git a/pkg/agent/controller/traceflow/packetin_test.go b/pkg/agent/controller/traceflow/packetin_test.go index c631a0305fe..68868d9f632 100644 --- a/pkg/agent/controller/traceflow/packetin_test.go +++ b/pkg/agent/controller/traceflow/packetin_test.go @@ -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") }) diff --git a/pkg/agent/multicast/mcast_controller_test.go b/pkg/agent/multicast/mcast_controller_test.go index b0399e7d6bd..bce31640b59 100644 --- a/pkg/agent/multicast/mcast_controller_test.go +++ b/pkg/agent/multicast/mcast_controller_test.go @@ -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) diff --git a/pkg/agent/multicast/mcast_discovery.go b/pkg/agent/multicast/mcast_discovery.go index c5c4a2d80c3..16bc2ba9e17 100644 --- a/pkg/agent/multicast/mcast_discovery.go +++ b/pkg/agent/multicast/mcast_discovery.go @@ -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()) @@ -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 diff --git a/pkg/agent/openflow/packetin.go b/pkg/agent/openflow/packetin.go index b51e534ac6b..c6aed161ec4 100644 --- a/pkg/agent/openflow/packetin.go +++ b/pkg/agent/openflow/packetin.go @@ -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" @@ -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)} +} diff --git a/pkg/agent/openflow/pipeline.go b/pkg/agent/openflow/pipeline.go index 97f956a31f8..9f1c92c6c4c 100644 --- a/pkg/agent/openflow/pipeline.go +++ b/pkg/agent/openflow/pipeline.go @@ -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} diff --git a/pkg/ovs/openflow/ofctrl_action.go b/pkg/ovs/openflow/ofctrl_action.go index 0604f00164f..ee5a0fca6d5 100644 --- a/pkg/ovs/openflow/ofctrl_action.go +++ b/pkg/ovs/openflow/ofctrl_action.go @@ -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 { @@ -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 } @@ -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<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), @@ -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%x/0xffffffff->ct_label)", ruleID, conjReg, nextTable, ruleID)} testFunc(t, ofTestUtils.OfctlFlowMatch(flowList, ruleTable, flow), "Failed to update conjunction action flow") - useIPv4 := false useIPv6 := false diff --git a/test/integration/ovs/ofctrl_test.go b/test/integration/ovs/ofctrl_test.go index ee3aeb75f1d..1cc40e8a3e9 100644 --- a/test/integration/ovs/ofctrl_test.go +++ b/test/integration/ovs/ofctrl_test.go @@ -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" @@ -627,7 +628,7 @@ 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) @@ -635,7 +636,7 @@ func TestPacketOutIn(t *testing.T) { 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) @@ -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())},