Skip to content

Commit

Permalink
OpenFlow1.5 support
Browse files Browse the repository at this point in the history
1. Consume messages defined in OpenFlow1.5
2. Use set_field instead of load, and use copy_field instead of move
3. The type of PacketIn.Data and PacketOut.Data is changed to Buffer in
   libOpenflow, so a conversion from Buffer to Ethernet is needed in
   both logic and tests
4. Parse matches set NXM_NX_REGX via message OXM_CLASS_PACKET_REGS in
   packetIn message. xreg (64bit) is used in OpenFlow1.5 in PacketIn to
   provide OVS register settings, a convention from xreg to reg (32bit)
   is used in functions.
5. Meter works as an Action instead of Instruction in OpenFlow1.5. So
   Antrea needs to apply MeterAction if the meter id is expected to be
   consumed in flow actions.

Signed-off-by: wenyingd <wenyingd@vmware.com>
  • Loading branch information
wenyingd committed Aug 4, 2022
1 parent 2a37aec commit c06413f
Show file tree
Hide file tree
Showing 35 changed files with 568 additions and 353 deletions.
8 changes: 4 additions & 4 deletions docs/antctl.md
Original file line number Diff line number Diff line change
Expand Up @@ -282,10 +282,10 @@ Example outputs of dumping Pod and NetworkPolicy OVS flows:
# Dump OVS flows of Pod "coredns-6955765f44-zcbwj"
$ antctl get of -p coredns-6955765f44-zcbwj -n kube-system
FLOW
table=classification, n_packets=513122, n_bytes=42615080, priority=190,in_port="coredns--d0c58e" actions=load:0x2->NXM_NX_REG0[0..15],resubmit(,10)
table=classification, n_packets=513122, n_bytes=42615080, priority=190,in_port="coredns--d0c58e" actions=set_field:0x2/0xffff->reg0,resubmit(,10)
table=10, n_packets=513122, n_bytes=42615080, priority=200,ip,in_port="coredns--d0c58e",dl_src=52:bd:c6:e0:eb:c1,nw_src=172.100.1.7 actions=resubmit(,30)
table=10, n_packets=0, n_bytes=0, priority=200,arp,in_port="coredns--d0c58e",arp_spa=172.100.1.7,arp_sha=52:bd:c6:e0:eb:c1 actions=resubmit(,20)
table=80, n_packets=556468, n_bytes=166477824, priority=200,dl_dst=52:bd:c6:e0:eb:c1 actions=load:0x5->NXM_NX_REG1[],load:0x1->NXM_NX_REG0[16],resubmit(,90)
table=80, n_packets=556468, n_bytes=166477824, priority=200,dl_dst=52:bd:c6:e0:eb:c1 actions=load:0x5->NXM_NX_REG1[],set_field:0x10000/0x10000->reg0,resubmit(,90)
table=70, n_packets=0, n_bytes=0, priority=200,ip,dl_dst=aa:bb:cc:dd:ee:ff,nw_dst=172.100.1.7 actions=set_field:62:39:b4:e8:05:76->eth_src,set_field:52:bd:c6:e0:eb:c1->eth_dst,dec_ttl,resubmit(,80)
# Get NetworkPolicies applied to Pod "coredns-6955765f44-zcbwj"
Expand Down Expand Up @@ -378,8 +378,8 @@ result: |
dec_ttl
resubmit(,80)
80. dl_dst=52:bd:c6:e0:eb:c1, priority 200, cookie 0x5e030000000000
load:0x5->NXM_NX_REG1[]
load:0x1->NXM_NX_REG0[16]
set_field:0x5->reg1
set_field:0x10000/0x10000->reg0
resubmit(,90)
90. conj_id=2,ip, priority 190, cookie 0x5e050000000000
resubmit(,105)
Expand Down
28 changes: 14 additions & 14 deletions docs/design/ovs-pipeline.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,10 +234,10 @@ should be performed for the packet in [L3ForwardingTable].
If you dump the flows for this table, you may see the following:

```text
1. table=0, priority=200,in_port=2 actions=load:0x1->NXM_NX_REG0[0..3],resubmit(,10)
2. table=0, priority=200,in_port=1 actions=load:0->NXM_NX_REG0[0..3],load:0x1->NXM_NX_REG0[19],resubmit(,30)
3. table=0, priority=190,in_port=4 actions=load:0x2->NXM_NX_REG0[0..3],resubmit(,10)
4. table=0, priority=190,in_port=3 actions=load:0x2->NXM_NX_REG0[0..3],resubmit(,10)
1. table=0, priority=200,in_port=2 actions=set_field:0x1/0xf->reg0,resubmit(,10)
2. table=0, priority=200,in_port=1 actions=set_field:0/0xf->reg0,load:0x1->NXM_NX_REG0[19],resubmit(,30)
3. table=0, priority=190,in_port=4 actions=set_field:0x2/0xf->reg0,resubmit(,10)
4. table=0, priority=190,in_port=3 actions=set_field:0x2/0xf->reg0,resubmit(,10)
5. table=0, priority=0 actions=drop
```

Expand Down Expand Up @@ -305,7 +305,7 @@ address for all the traffic being tunnelled.
If you dump the flows for this table, you may see the following:

```text
1. table=20, priority=200,arp,arp_tpa=10.10.1.1,arp_op=1 actions=move:NXM_OF_ETH_SRC[]->NXM_OF_ETH_DST[],mod_dl_src:aa:bb:cc:dd:ee:ff,load:0x2->NXM_OF_ARP_OP[],move:NXM_NX_ARP_SHA[]->NXM_NX_ARP_THA[],load:0xaabbccddeeff->NXM_NX_ARP_SHA[],move:NXM_OF_ARP_SPA[]->NXM_OF_ARP_TPA[],load:0xa0a0101->NXM_OF_ARP_SPA[],IN_PORT
1. table=20, priority=200,arp,arp_tpa=10.10.1.1,arp_op=1 actions=move:NXM_OF_ETH_SRC[]->NXM_OF_ETH_DST[],mod_dl_src:aa:bb:cc:dd:ee:ff,set_field:2->arp_op,move:NXM_NX_ARP_SHA[]->NXM_NX_ARP_THA[],load:0xaabbccddeeff->NXM_NX_ARP_SHA[],move:NXM_OF_ARP_SPA[]->NXM_OF_ARP_TPA[],load:0xa0a0101->NXM_OF_ARP_SPA[],IN_PORT
2. table=20, priority=190,arp actions=NORMAL
3. table=20, priority=0 actions=drop
```
Expand Down Expand Up @@ -781,7 +781,7 @@ table=70, priority=210,ct_state=+rpl+trk,ct_mark=0x20,ip actions=mod_dl_dst:e2:e
For a given peer Node, the flow may look like this:

```text
table=70, priority=200,ip,nw_dst=10.10.1.0/24 actions=mod_dl_src:e2:e5:a4:9b:1c:b1,mod_dl_dst:aa:bb:cc:dd:ee:ff,load:0x1->NXM_NX_REG1[],load:0x1->NXM_NX_REG0[16],load:0xc0a80102->NXM_NX_TUN_IPV4_DST[],goto_table:72
table=70, priority=200,ip,nw_dst=10.10.1.0/24 actions=mod_dl_src:e2:e5:a4:9b:1c:b1,mod_dl_dst:aa:bb:cc:dd:ee:ff,load:0x1->NXM_NX_REG1[],set_field:0x10000/0x10000->reg0,load:0xc0a80102->NXM_NX_TUN_IPV4_DST[],goto_table:72
```

If none of the flows described above are hit, traffic goes directly to
Expand Down Expand Up @@ -842,7 +842,7 @@ the right SNAT IP (Antrea Agent adds an iptables SNAT rule for each local SNAT
IP that matches the ID).

```text
table=71, priority=200,ct_state=+new+trk,ip,in_port="pod1-7e503a" actions=load:0x1->NXM_NX_PKT_MARK[0..7],goto_table:80
table=71, priority=200,ct_state=+new+trk,ip,in_port="pod1-7e503a" actions=set_field:0x1/0xff->pkt_mark,goto_table:80
```

When the SNAT IP of the Egress is on a remote Node, the flow will tunnel the
Expand All @@ -853,7 +853,7 @@ destination MAC addresses, load the SNAT IP to NXM_NX_TUN_IPV4_DST, and send the
packets to [L3DecTTLTable].

```text
table=71, priority=200,ct_state=+new+trk,ip,in_port="pod2-357c21" actions=mod_dl_src:e2:e5:a4:9b:1c:b1,mod_dl_dst:aa:bb:cc:dd:ee:ff,load:0x1->NXM_NX_REG1[],load:0x1->NXM_NX_REG0[16],load:0xc0a80a66->NXM_NX_TUN_IPV4_DST[],goto_table:72
table=71, priority=200,ct_state=+new+trk,ip,in_port="pod2-357c21" actions=mod_dl_src:e2:e5:a4:9b:1c:b1,mod_dl_dst:aa:bb:cc:dd:ee:ff,load:0x1->NXM_NX_REG1[],set_field:0x10000/0x10000->reg0,load:0xc0a80a66->NXM_NX_TUN_IPV4_DST[],goto_table:72
```

Last, when a SNAT IP configured for Egresses is on the local Node, an additional
Expand All @@ -862,7 +862,7 @@ use the SNAT IP. The flow matches the tunnel destination IP (which should be
equal to the SNAT IP), and sets the 8 bits ID of the SNAT IP to pkt_mark.

```text
table=71, priority=200,ct_state=+new+trk,ip,tun_dst="192.168.10.101" actions=load:0x1->NXM_NX_PKT_MARK[0..7],goto_table:80
table=71, priority=200,ct_state=+new+trk,ip,tun_dst="192.168.10.101" actions=set_field:0x1/0xff->pkt_mark,goto_table:80
```

### L3DecTTLTable (72)
Expand Down Expand Up @@ -891,10 +891,10 @@ port (tunnel port, gateway port, and local Pod ports), as you can see if you
dump the flows:

```text
1. table=80, priority=200,dl_dst=aa:bb:cc:dd:ee:ff actions=load:0x1->NXM_NX_REG1[],load:0x1->NXM_NX_REG0[16],goto_table:105
2. table=80, priority=200,dl_dst=e2:e5:a4:9b:1c:b1 actions=load:0x2->NXM_NX_REG1[],load:0x1->NXM_NX_REG0[16],goto_table:105
3. table=80, priority=200,dl_dst=12:9e:a6:47:d0:70 actions=load:0x3->NXM_NX_REG1[],load:0x1->NXM_NX_REG0[16],goto_table:90
4. table=80, priority=200,dl_dst=ba:a8:13:ca:ed:cf actions=load:0x4->NXM_NX_REG1[],load:0x1->NXM_NX_REG0[16],goto_table:90
1. table=80, priority=200,dl_dst=aa:bb:cc:dd:ee:ff actions=set_field:0x1->reg1,set_field:0x10000/0x10000->reg0,goto_table:105
2. table=80, priority=200,dl_dst=e2:e5:a4:9b:1c:b1 actions=set_field:0x2->reg1,set_field:0x10000/0x10000->reg0,goto_table:105
3. table=80, priority=200,dl_dst=12:9e:a6:47:d0:70 actions=set_field:0x3->reg1,set_field:0x10000/0x10000->reg0,goto_table:90
4. table=80, priority=200,dl_dst=ba:a8:13:ca:ed:cf actions=set_field:0x4->reg1,set_field:0x10000/0x10000->reg0,goto_table:90
5. table=80, priority=0 actions=goto_table:105
```

Expand Down Expand Up @@ -1149,7 +1149,7 @@ across the different backends for each Service.
If you dump the flows for this table, you should see something like this:

```text
1. table=40, priority=200,ip,nw_dst=10.96.0.0/12 actions=load:0x2->NXM_NX_REG1[],load:0x1->NXM_NX_REG0[16],goto_table:105
1. table=40, priority=200,ip,nw_dst=10.96.0.0/12 actions=set_field:0x2->reg1,load:0x1->NXM_NX_REG0[16],goto_table:105
2. table=40, priority=0 actions=goto_table:45
```

Expand Down
2 changes: 1 addition & 1 deletion docs/design/windows-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ table=70, priority=200,ip,nw_dst=$peerPodSubnet actions=mod_dl_dst:$peerNodeMAC,
table=70, priority=200,ct_state=+rpl+trk,ip,nw_dst=$peerNodeIP actions=mod_dl_dst:$peerNodeMAC,resubmit(,80)
L2ForwardingCalcTable: 80
table=80, priority=200,dl_dst=$peerNodeMAC actions=load:$uplink->NXM_NX_REG1[],load:0x1->NXM_NX_REG0[16],resubmit(,105)
table=80, priority=200,dl_dst=$peerNodeMAC actions=load:$uplink->NXM_NX_REG1[],set_field:0x10000/0x10000->reg0,resubmit(,105)
```

### SNAT configuration
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ module antrea.io/antrea
go 1.17

require (
antrea.io/libOpenflow v0.6.2
antrea.io/ofnet v0.5.7
antrea.io/libOpenflow v0.8.0
antrea.io/ofnet v0.6.0
github.com/ClickHouse/clickhouse-go v1.5.4
github.com/DATA-DOG/go-sqlmock v1.5.0
github.com/Mellanox/sriovnet v1.1.0
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
antrea.io/libOpenflow v0.6.2 h1:1JMSJ7Lp7yOhKybHey9VDtRI6JuIgkhUWJBX5GIFY9I=
antrea.io/libOpenflow v0.6.2/go.mod h1:CzEJZxDNAupiGxeL5VOw92PsxfyvehEAvE3PiC6gr8o=
antrea.io/ofnet v0.5.7 h1:x0q0lZqp05wu01gk1+S5S15FmIpmTGPhi/z/aIDmuMw=
antrea.io/ofnet v0.5.7/go.mod h1:8TJVF6MLe9/gZ/KbhGUvULs9/TxssepEaYEe+o1SEgs=
antrea.io/libOpenflow v0.8.0 h1:Xm6mlSqdXtDD418nf1lndoDvMi8scqUan8pkEUZ2oas=
antrea.io/libOpenflow v0.8.0/go.mod h1:CzEJZxDNAupiGxeL5VOw92PsxfyvehEAvE3PiC6gr8o=
antrea.io/ofnet v0.6.0 h1:XuZ1WjOd0R8nIdRG7bfCF1AryLLlaroFjrgnIDfR1Vg=
antrea.io/ofnet v0.6.0/go.mod h1:qWqi11pI3kBYcS9SYWm92ZOiOPBx04Jx21cDmJlJhOg=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
Expand Down
18 changes: 13 additions & 5 deletions pkg/agent/controller/networkpolicy/fqdn.go
Original file line number Diff line number Diff line change
Expand Up @@ -756,7 +756,11 @@ func (f *fqdnController) handlePacketIn(pktIn *ofctrl.PacketIn) error {
f.onDNSResponseMsg(&dnsMsg, time.Now(), waitCh)
}
go func() {
switch ipPkt := pktIn.Data.Data.(type) {
ethernetPkt, err := getEthernetPacket(pktIn)
if err != nil {
return
}
switch ipPkt := ethernetPkt.Data.(type) {
case *protocol.IPv4:
switch dnsPkt := ipPkt.Data.(type) {
case *protocol.UDP:
Expand Down Expand Up @@ -789,7 +793,11 @@ func (f *fqdnController) sendDNSPacketout(pktIn *ofctrl.PacketIn) error {
prot uint8
isIPv6 bool
)
switch ipPkt := pktIn.Data.Data.(type) {
ethernetPkt, err := getEthernetPacket(pktIn)
if err != nil {
return err
}
switch ipPkt := ethernetPkt.Data.(type) {
case *protocol.IPv4:
srcIP = ipPkt.NWSrc.String()
dstIP = ipPkt.NWDst.String()
Expand Down Expand Up @@ -820,7 +828,7 @@ func (f *fqdnController) sendDNSPacketout(pktIn *ofctrl.PacketIn) error {
inPort = inPortField.GetValue().(uint32)
}
}
udpSrcPort, udpDstPort, err := binding.GetUDPHeaderData(pktIn.Data.Data)
udpSrcPort, udpDstPort, err := binding.GetUDPHeaderData(ethernetPkt.Data)
if err != nil {
klog.ErrorS(err, "Failed to get UDP header data")
return err
Expand All @@ -829,8 +837,8 @@ func (f *fqdnController) sendDNSPacketout(pktIn *ofctrl.PacketIn) error {
return packetOutBuilder.AddLoadRegMark(openflow.CustomReasonDNSRegMark)
}
return f.ofClient.SendUDPPacketOut(
pktIn.Data.HWSrc.String(),
pktIn.Data.HWDst.String(),
ethernetPkt.HWSrc.String(),
ethernetPkt.HWDst.String(),
srcIP,
dstIP,
inPort,
Expand Down
16 changes: 13 additions & 3 deletions pkg/agent/controller/networkpolicy/packetin.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ import (
"net"
"time"

"antrea.io/libOpenflow/openflow13"
"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 @@ -70,7 +72,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.GetMatchFieldByRegID(matchers, field.GetRegID())
}

// getMatch receives ofctrl matchers and table id, match field.
Expand All @@ -95,7 +97,7 @@ func getMatch(matchers *ofctrl.Matchers, tableID uint8, disposition uint32) *ofc
}

// getInfoInReg unloads and returns data stored in the match field.
func getInfoInReg(regMatch *ofctrl.MatchField, rng *openflow13.NXRange) (uint32, error) {
func getInfoInReg(regMatch *ofctrl.MatchField, rng *openflow15.NXRange) (uint32, error) {
regValue, ok := regMatch.GetValue().(*ofctrl.NXRegister)
if !ok {
return 0, errors.New("register value cannot be retrieved")
Expand Down Expand Up @@ -208,3 +210,11 @@ 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 {
return nil, fmt.Errorf("failed to parse ethernet packet from packet-in message: %v", err)
}
return ethernetPkt, nil
}
22 changes: 13 additions & 9 deletions pkg/agent/controller/networkpolicy/reject.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
"encoding/binary"
"fmt"

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

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

var (
srcIP string
dstIP string
proto uint8
isIPv6 bool
)
switch ipPkt := pktIn.Data.Data.(type) {
switch ipPkt := ethernetPkt.Data.(type) {
case *protocol.IPv4:
// Get IP data.
srcIP = ipPkt.NWDst.String()
Expand Down Expand Up @@ -152,17 +156,17 @@ func (c *Controller) rejectRequest(pktIn *ofctrl.PacketIn) error {
}
tunPort := c.tunPort
if tunPort == 0 {
// openflow13.P_CONTROLLER is used with noEncap mode when tunnel interface is not found.
// It won't cause a loop with openflow13.P_CONTROLLER because it is used as the input port but not output port
// openflow15.P_CONTROLLER is used with noEncap mode when tunnel interface is not found.
// It won't cause a loop with openflow15.P_CONTROLLER because it is used as the input port but not output port
// in the packet out message.
tunPort = uint32(openflow13.P_CONTROLLER)
tunPort = uint32(openflow15.P_CONTROLLER)
}
inPort, outPort := getRejectOFPorts(packetOutType, sIface, dIface, c.gwPort, tunPort)
mutateFunc := getRejectPacketOutMutateFunc(packetOutType)

if proto == protocol.Type_TCP {
// Get TCP data.
oriTCPSrcPort, oriTCPDstPort, oriTCPSeqNum, _, _, err := binding.GetTCPHeaderData(pktIn.Data.Data)
oriTCPSrcPort, oriTCPDstPort, oriTCPSeqNum, _, _, err := binding.GetTCPHeaderData(ethernetPkt.Data)
if err != nil {
return err
}
Expand Down Expand Up @@ -191,7 +195,7 @@ func (c *Controller) rejectRequest(pktIn *ofctrl.PacketIn) error {
icmpCode = ICMPv6DstAdminProhibitedCode
ipHdrLen = IPv6HdrLen
}
ipHdr, _ := pktIn.Data.Data.MarshalBinary()
ipHdr, _ := ethernetPkt.Data.MarshalBinary()
icmpData := make([]byte, int(ICMPUnusedHdrLen+ipHdrLen+8))
// Put ICMP unused header in Data prop and set it to zero.
binary.BigEndian.PutUint32(icmpData[:ICMPUnusedHdrLen], 0)
Expand Down
30 changes: 17 additions & 13 deletions pkg/agent/controller/traceflow/packetin.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ import (
"net"
"time"

"antrea.io/libOpenflow/openflow13"
"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 All @@ -39,8 +40,7 @@ func (c *Controller) HandlePacketIn(pktIn *ofctrl.PacketIn) error {
}
oldTf, nodeResult, packet, err := c.parsePacketIn(pktIn)
if err != nil {
klog.Errorf("parsePacketIn error: %+v", err)
return err
return fmt.Errorf("parsePacketIn error: %v", err)
}

// Retry when update CRD conflict which caused by multiple agents updating one CRD at same time.
Expand All @@ -64,9 +64,9 @@ func (c *Controller) HandlePacketIn(pktIn *ofctrl.PacketIn) error {
return nil
})
if err != nil {
klog.Errorf("Update traceflow error: %+v", err)
return fmt.Errorf("update traceflow error: %v", err)
}
return err
return nil
}

func (c *Controller) parsePacketIn(pktIn *ofctrl.PacketIn) (*crdv1alpha1.Traceflow, *crdv1alpha1.NodeResult, *crdv1alpha1.Packet, error) {
Expand All @@ -77,8 +77,12 @@ func (c *Controller) parsePacketIn(pktIn *ofctrl.PacketIn) (*crdv1alpha1.Tracefl
var err error
var tag uint8
var ctNwDst, ctNwSrc, ipDst, ipSrc string
if pktIn.Data.Ethertype == protocol.IPv4_MSG {
ipPacket, ok := pktIn.Data.Data.(*protocol.IPv4)
etherData := new(protocol.Ethernet)
if err := etherData.UnmarshalBinary(pktIn.Data.(*util.Buffer).Bytes()); err != nil {
return nil, nil, nil, fmt.Errorf("failed to parse Ethernet packet from packet-in message: %v", err)
}
if etherData.Ethertype == protocol.IPv4_MSG {
ipPacket, ok := etherData.Data.(*protocol.IPv4)
if !ok {
return nil, nil, nil, errors.New("invalid traceflow IPv4 packet")
}
Expand All @@ -93,8 +97,8 @@ func (c *Controller) parsePacketIn(pktIn *ofctrl.PacketIn) (*crdv1alpha1.Tracefl
}
ipDst = ipPacket.NWDst.String()
ipSrc = ipPacket.NWSrc.String()
} else if pktIn.Data.Ethertype == protocol.IPv6_MSG {
ipv6Packet, ok := pktIn.Data.Data.(*protocol.IPv6)
} else if etherData.Ethertype == protocol.IPv6_MSG {
ipv6Packet, ok := etherData.Data.(*protocol.IPv6)
if !ok {
return nil, nil, nil, errors.New("invalid traceflow IPv6 packet")
}
Expand All @@ -110,7 +114,7 @@ func (c *Controller) parsePacketIn(pktIn *ofctrl.PacketIn) (*crdv1alpha1.Tracefl
ipDst = ipv6Packet.NWDst.String()
ipSrc = ipv6Packet.NWSrc.String()
} else {
return nil, nil, nil, fmt.Errorf("unsupported traceflow packet Ethertype: %d", pktIn.Data.Ethertype)
return nil, nil, nil, fmt.Errorf("unsupported traceflow packet Ethertype: %d", etherData.Ethertype)
}

firstPacket := false
Expand Down Expand Up @@ -246,7 +250,7 @@ func (c *Controller) parsePacketIn(pktIn *ofctrl.PacketIn) (*crdv1alpha1.Tracefl
}
}
gatewayIP := c.nodeConfig.GatewayConfig.IPv4
if pktIn.Data.Ethertype == protocol.IPv6_MSG {
if etherData.Ethertype == protocol.IPv6_MSG {
gatewayIP = c.nodeConfig.GatewayConfig.IPv6
}
gwPort := c.nodeConfig.GatewayConfig.OFPort
Expand Down Expand Up @@ -274,7 +278,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.GetMatchFieldByRegID(matchers, field.GetRegID())
}

func getMatchTunnelDstField(matchers *ofctrl.Matchers, isIPv6 bool) *ofctrl.MatchField {
Expand All @@ -284,7 +288,7 @@ func getMatchTunnelDstField(matchers *ofctrl.Matchers, isIPv6 bool) *ofctrl.Matc
return matchers.GetMatchByName("NXM_NX_TUN_IPV4_DST")
}

func getRegValue(regMatch *ofctrl.MatchField, rng *openflow13.NXRange) (uint32, error) {
func getRegValue(regMatch *ofctrl.MatchField, rng *openflow15.NXRange) (uint32, error) {
regValue, ok := regMatch.GetValue().(*ofctrl.NXRegister)
if !ok {
return 0, errors.New("register value cannot be got")
Expand Down
6 changes: 5 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,11 @@ 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.NewEthernet()
etherPkt.Ethertype = ethType
etherPkt.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
Loading

0 comments on commit c06413f

Please sign in to comment.