-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: add tests for the dscp module
- Loading branch information
Showing
10 changed files
with
259 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,26 @@ | ||
#include <stdint.h> | ||
#pragma once | ||
|
||
#include <rte_ip.h> | ||
#include <stdint.h> | ||
|
||
#define DSCP_MARK_NEVER 0 | ||
#define DSCP_MARK_DEFAULT 1 | ||
#define DSCP_MARK_ALWAYS 2 | ||
|
||
#define DSCP_MARK_MASK 0xFC | ||
#define DSCP_MARK_SHIFT 2 | ||
#define DSCP_ECN_MASK 0x03 | ||
|
||
// #include <rte_ip.h> | ||
struct rte_ipv4_hdr; | ||
struct rte_ipv6_hdr; | ||
|
||
struct dscp_config { | ||
uint8_t flag; | ||
uint8_t tc; | ||
uint8_t mark; | ||
}; | ||
|
||
int | ||
dscp_mark_v4(struct rte_ipv4_hdr *header, struct dscp_config config); | ||
dscp_mark_v4(struct rte_ipv4_hdr *ip4_hdr, struct dscp_config config); | ||
|
||
int | ||
dscp_mark_v6(struct rte_ipv6_hdr *header, struct dscp_config config); | ||
dscp_mark_v6(struct rte_ipv6_hdr *ip6_hdr, struct dscp_config config); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,16 @@ | ||
#pragma once | ||
|
||
#include <stdint.h> | ||
|
||
#include "dataplane/module/module.h" | ||
#include "dataplane/packet/dscp.h" | ||
#include "lpm.h" | ||
|
||
struct dscp_module_config { | ||
struct module_config config; | ||
|
||
struct lpm lpm_v4; | ||
struct lpm lpm_v6; | ||
struct dscp_config dscp; | ||
}; | ||
|
||
struct module * | ||
new_module_kernel(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package dscp_test | ||
|
||
//#cgo CFLAGS: -I../../../.. -I../../../../lib -I../../../../common | ||
//#cgo LDFLAGS: -L../../../../build/modules/dscp -ldscp_dp | ||
//#cgo LDFLAGS: -L../../../../build/lib/dataplane/packet -lpacket | ||
/* | ||
#include "lib/dataplane/packet/dscp.h" | ||
#include "modules/dscp/dataplane.h" | ||
uint8_t dscp_mark_never = DSCP_MARK_NEVER; | ||
uint8_t dscp_mark_default = DSCP_MARK_DEFAULT; | ||
uint8_t dscp_mark_always = DSCP_MARK_ALWAYS; | ||
void | ||
dscp_handle_packets( | ||
struct module *module, | ||
struct module_config *config, | ||
struct packet_front *packet_front | ||
); | ||
*/ | ||
import "C" | ||
import ( | ||
"net/netip" | ||
"unsafe" | ||
|
||
"tests/common" | ||
|
||
"github.com/gopacket/gopacket" | ||
) | ||
|
||
var ( | ||
DSCPMarkNever uint8 = uint8(C.dscp_mark_never) | ||
DSCPMarkAlways uint8 = uint8(C.dscp_mark_always) | ||
DSCPMarkDefault uint8 = uint8(C.dscp_mark_default) | ||
) | ||
|
||
func dscpModuleConfig(prefixes []netip.Prefix, flag, dscp uint8) C.struct_dscp_module_config { | ||
m := C.struct_dscp_module_config{ | ||
config: C.struct_module_config{}, | ||
} | ||
lpm4, lpm6 := common.BuildLPMs(prefixes) | ||
m.lpm_v4 = *(*C.struct_lpm)(unsafe.Pointer(&lpm4)) | ||
m.lpm_v6 = *(*C.struct_lpm)(unsafe.Pointer(&lpm6)) | ||
m.flag = C.uint8_t(flag) | ||
m.dscp = C.uint8_t(dscp) | ||
|
||
return m | ||
} | ||
|
||
func dscpHandlePackets(mc *C.struct_dscp_module_config, packets ...gopacket.Packet) common.PacketFrontResult { | ||
payload := common.PacketsToPaylod(packets) | ||
pinner, pf := common.PacketFrontFromPayload(payload) | ||
common.ParsePackets(pf) | ||
C.dscp_handle_packets(nil, &mc.config, (*C.struct_packet_front)(unsafe.Pointer(pf))) | ||
result := common.PacketFrontToPayload(pf) | ||
pinner.Unpin() | ||
return result | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
package dscp_test | ||
|
||
import ( | ||
"fmt" | ||
"net" | ||
"net/netip" | ||
"testing" | ||
|
||
"tests/common" | ||
|
||
"github.com/google/go-cmp/cmp" | ||
"github.com/google/go-cmp/cmp/cmpopts" | ||
"github.com/gopacket/gopacket" | ||
"github.com/gopacket/gopacket/layers" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func mark(t *testing.T, pkt gopacket.Packet, dscp uint8) gopacket.Packet { | ||
network := pkt.NetworkLayer() | ||
tc := dscp << 2 // ECN in the first two bits | ||
switch network.LayerType() { | ||
case layers.LayerTypeIPv4: | ||
network.(*layers.IPv4).TOS = tc | ||
case layers.LayerTypeIPv6: | ||
network.(*layers.IPv6).TrafficClass = tc | ||
default: | ||
t.Logf("unexpected network layer type: %v", network.LayerType()) | ||
t.FailNow() | ||
} | ||
// Serialize and then Deserialize the packet so, the gopacket will recalculate checksum for us. | ||
buf := gopacket.NewSerializeBuffer() | ||
opts := gopacket.SerializeOptions{ | ||
FixLengths: true, | ||
ComputeChecksums: true, | ||
} | ||
require.NoError(t, gopacket.SerializePacket(buf, opts, pkt)) | ||
|
||
pkt = gopacket.NewPacket( | ||
buf.Bytes(), | ||
layers.LayerTypeEthernet, | ||
gopacket.Default, | ||
) | ||
require.Empty(t, pkt.ErrorLayer()) | ||
return pkt | ||
} | ||
|
||
func TestDSCP(t *testing.T) { | ||
eth := layers.Ethernet{ | ||
SrcMAC: common.Unwrap(net.ParseMAC("00:00:00:00:00:01")), | ||
DstMAC: common.Unwrap(net.ParseMAC("00:11:22:33:44:55")), | ||
EthernetType: layers.EthernetTypeDot1Q, | ||
} | ||
eth4 := eth | ||
eth4.EthernetType = layers.EthernetTypeIPv4 | ||
eth6 := eth | ||
eth6.EthernetType = layers.EthernetTypeIPv6 | ||
|
||
vlan4 := layers.Dot1Q{ | ||
VLANIdentifier: 100, | ||
Type: layers.EthernetTypeIPv4, | ||
} | ||
vlan6 := vlan4 | ||
vlan6.Type = layers.EthernetTypeIPv6 | ||
|
||
ip6 := layers.IPv6{ | ||
Version: 6, | ||
NextHeader: layers.IPProtocolICMPv4, | ||
HopLimit: 64, | ||
SrcIP: net.IPv6zero, | ||
DstIP: net.ParseIP("1:2:3:4::abcd"), | ||
} | ||
ip4 := layers.IPv4{ | ||
Version: 4, | ||
Id: 1, | ||
TTL: 64, | ||
Protocol: layers.IPProtocolICMPv4, | ||
SrcIP: net.IPv4zero, | ||
DstIP: net.ParseIP("1.1.0.0"), | ||
} | ||
icmp := layers.ICMPv4{ | ||
TypeCode: layers.CreateICMPv4TypeCode( | ||
layers.ICMPv4TypeEchoRequest, | ||
layers.ICMPv4CodeNet, | ||
), | ||
} | ||
|
||
prefixes := []netip.Prefix{ | ||
common.Unwrap(netip.ParsePrefix("1:2:3:4::/64")), | ||
common.Unwrap(netip.ParsePrefix("1.1.0.0/32")), | ||
} | ||
|
||
testData := []struct { | ||
name string | ||
pkt gopacket.Packet | ||
}{ | ||
{"v4", common.LayersToPacket(t, ð4, &ip4, &icmp)}, | ||
{"v6", common.LayersToPacket(t, ð6, &ip6, &icmp)}, | ||
{"vlan>v4", common.LayersToPacket(t, ð, &vlan4, &ip4, &icmp)}, | ||
{"vlan>v6", common.LayersToPacket(t, ð, &vlan6, &ip6, &icmp)}, | ||
} | ||
|
||
cases := []struct { | ||
name string | ||
flag uint8 | ||
mark uint8 // DSCP value in the module config | ||
from uint8 // original DSCP value of the packet | ||
expt uint8 // expected DSCP value | ||
}{ | ||
{"Never remark 0->10=10", DSCPMarkNever, 0, 10, 10}, | ||
{"Never remark 0-> 0= 0", DSCPMarkNever, 0, 0, 0}, | ||
{"Never remark 7->60=60", DSCPMarkNever, 7, 60, 60}, | ||
{"Never remark 7->70=70", DSCPMarkNever, 7, 70, 70}, | ||
|
||
{"Always mark 40-> 0=40", DSCPMarkAlways, 40, 0, 40}, | ||
{"Always mark 7 ->16= 7", DSCPMarkAlways, 7, 16, 7}, | ||
{"Always mark 10->26=10", DSCPMarkAlways, 10, 26, 10}, | ||
{"Always mark 0 ->36= 0", DSCPMarkAlways, 0, 36, 0}, | ||
|
||
{"Default mark 7 ->13=13", DSCPMarkDefault, 7, 13, 13}, | ||
{"Default mark 7 -> 0= 7", DSCPMarkDefault, 7, 0, 7}, | ||
{"Default mark 0 -> 1= 1", DSCPMarkDefault, 0, 1, 1}, | ||
{"Default mark 0 -> 0= 0", DSCPMarkDefault, 0, 0, 0}, | ||
} | ||
|
||
for _, c := range cases { | ||
for _, p := range testData { | ||
t.Run(fmt.Sprintf("pkt=%s: %s", p.name, c.name), func(t *testing.T) { | ||
pkt := mark(t, p.pkt, c.from) | ||
t.Log("Origin packet", pkt) | ||
|
||
m := dscpModuleConfig(prefixes, c.flag, c.mark) | ||
result := dscpHandlePackets(&m, pkt) | ||
require.NotEmpty(t, result.Output, "result.Output") | ||
|
||
resultPkt := common.ParseEtherPacket(result.Output[0]) | ||
t.Log("Result packet", resultPkt) | ||
|
||
expectedPkt := mark(t, p.pkt, c.expt) | ||
t.Log("Expected packet", expectedPkt) | ||
|
||
diff := cmp.Diff(expectedPkt.Layers(), resultPkt.Layers(), | ||
cmpopts.IgnoreUnexported(layers.IPv6{}, layers.ICMPv6{}), | ||
) | ||
require.Empty(t, diff) | ||
}) | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
sources = files( | ||
'dscp.go', | ||
'dscp_test.go', | ||
) | ||
|
||
test('dscp', | ||
find_program('go'), | ||
args: ['test', './...'], | ||
workdir: meson.current_source_dir(), | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
subdir('decap') | ||
subdir('dscp') |