Skip to content

Commit

Permalink
Add test for ebpf deparser
Browse files Browse the repository at this point in the history
Signed-off-by: Radostin Stoyanov <[email protected]>
  • Loading branch information
rst0git committed Mar 16, 2022
1 parent df118c7 commit a5fdc50
Show file tree
Hide file tree
Showing 8 changed files with 349 additions and 2 deletions.
5 changes: 3 additions & 2 deletions backends/ebpf/ebpfProgram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ bool EBPFProgram::build() {
::warning(ErrorType::WARN_INVALID, "%1%: the main ebpf package should be called ebpfFilter"
"; are you using the wrong architecture?", pack->type->name);

if (pack->getConstructorParameters()->size() != 2) {
auto nparam = pack->getConstructorParameters()->size();
if (nparam != 2 && nparam != 3) {
::error(ErrorType::ERR_EXPECTED,
"Expected toplevel package %1% to have 2 parameters", pack->type);
"Expected toplevel package %1% to have 2 or 3 parameters", pack->type);
return false;
}

Expand Down
53 changes: 53 additions & 0 deletions testdata/p4_16_samples/test_deparser_ebpf.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#include <core.p4>

#include "ebpf_headers.p4"

parser parse<H>(packet_in packet, out H headers);
control pipeline<H>(inout H headers, out bool accept);
@deparser
control deparser<H>(packet_out b, in H headers);

package ebpfFilter<H>(
parse<H> prs,
pipeline<H> filt,
deparser<H> dprs
);

struct Headers_t {
Ethernet_h ethernet;
IPv4_h ipv4;
}

parser prs(packet_in p, out Headers_t headers)
{
state start {
p.extract(headers.ethernet);
transition select(headers.ethernet.etherType) {
16w0x800 : ip;
default: reject;
}
}

state ip {
p.extract(headers.ipv4);
transition accept;
}
}

control pipe(inout Headers_t headers, out bool pass) {
apply {
pass = true;
if (headers.ipv4.isValid()) {
headers.ipv4.setInvalid();
}
}
}

control dprs(packet_out packet, in Headers_t headers) {
apply {
packet.emit(headers.ethernet);
packet.emit(headers.ipv4);
}
}

ebpfFilter(prs(), pipe(), dprs()) main;
2 changes: 2 additions & 0 deletions testdata/p4_16_samples/test_deparser_ebpf.stf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
packet 0 ffffffffffffaabbccddeeff08004500001400010000400096d50a14c9f008080808
expect 0 ffffffffffffaabbccddeeff9000
66 changes: 66 additions & 0 deletions testdata/p4_16_samples_outputs/test_deparser_ebpf-first.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#include <core.p4>

@ethernetaddress typedef bit<48> EthernetAddress;
@ipv4address typedef bit<32> IPv4Address;
header Ethernet_h {
EthernetAddress dstAddr;
EthernetAddress srcAddr;
bit<16> etherType;
}

header IPv4_h {
bit<4> version;
bit<4> ihl;
bit<8> diffserv;
bit<16> totalLen;
bit<16> identification;
bit<3> flags;
bit<13> fragOffset;
bit<8> ttl;
bit<8> protocol;
bit<16> hdrChecksum;
IPv4Address srcAddr;
IPv4Address dstAddr;
}

parser parse<H>(packet_in packet, out H headers);
control pipeline<H>(inout H headers, out bool accept);
@deparser control deparser<H>(packet_out b, in H headers);
package ebpfFilter<H>(parse<H> prs, pipeline<H> filt, deparser<H> dprs);
struct Headers_t {
Ethernet_h ethernet;
IPv4_h ipv4;
}

parser prs(packet_in p, out Headers_t headers) {
state start {
p.extract<Ethernet_h>(headers.ethernet);
transition select(headers.ethernet.etherType) {
16w0x800: ip;
default: reject;
}
}
state ip {
p.extract<IPv4_h>(headers.ipv4);
transition accept;
}
}

control pipe(inout Headers_t headers, out bool pass) {
apply {
pass = true;
if (headers.ipv4.isValid()) {
headers.ipv4.setInvalid();
}
}
}

control dprs(packet_out packet, in Headers_t headers) {
apply {
packet.emit<Ethernet_h>(headers.ethernet);
packet.emit<IPv4_h>(headers.ipv4);
}
}

ebpfFilter<Headers_t>(prs(), pipe(), dprs()) main;

66 changes: 66 additions & 0 deletions testdata/p4_16_samples_outputs/test_deparser_ebpf-frontend.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#include <core.p4>

@ethernetaddress typedef bit<48> EthernetAddress;
@ipv4address typedef bit<32> IPv4Address;
header Ethernet_h {
EthernetAddress dstAddr;
EthernetAddress srcAddr;
bit<16> etherType;
}

header IPv4_h {
bit<4> version;
bit<4> ihl;
bit<8> diffserv;
bit<16> totalLen;
bit<16> identification;
bit<3> flags;
bit<13> fragOffset;
bit<8> ttl;
bit<8> protocol;
bit<16> hdrChecksum;
IPv4Address srcAddr;
IPv4Address dstAddr;
}

parser parse<H>(packet_in packet, out H headers);
control pipeline<H>(inout H headers, out bool accept);
@deparser control deparser<H>(packet_out b, in H headers);
package ebpfFilter<H>(parse<H> prs, pipeline<H> filt, deparser<H> dprs);
struct Headers_t {
Ethernet_h ethernet;
IPv4_h ipv4;
}

parser prs(packet_in p, out Headers_t headers) {
state start {
p.extract<Ethernet_h>(headers.ethernet);
transition select(headers.ethernet.etherType) {
16w0x800: ip;
default: reject;
}
}
state ip {
p.extract<IPv4_h>(headers.ipv4);
transition accept;
}
}

control pipe(inout Headers_t headers, out bool pass) {
apply {
pass = true;
if (headers.ipv4.isValid()) {
headers.ipv4.setInvalid();
}
}
}

control dprs(packet_out packet, in Headers_t headers) {
apply {
packet.emit<Ethernet_h>(headers.ethernet);
packet.emit<IPv4_h>(headers.ipv4);
}
}

ebpfFilter<Headers_t>(prs(), pipe(), dprs()) main;

93 changes: 93 additions & 0 deletions testdata/p4_16_samples_outputs/test_deparser_ebpf-midend.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#include <core.p4>

@ethernetaddress typedef bit<48> EthernetAddress;
@ipv4address typedef bit<32> IPv4Address;
header Ethernet_h {
EthernetAddress dstAddr;
EthernetAddress srcAddr;
bit<16> etherType;
}

header IPv4_h {
bit<4> version;
bit<4> ihl;
bit<8> diffserv;
bit<16> totalLen;
bit<16> identification;
bit<3> flags;
bit<13> fragOffset;
bit<8> ttl;
bit<8> protocol;
bit<16> hdrChecksum;
IPv4Address srcAddr;
IPv4Address dstAddr;
}

parser parse<H>(packet_in packet, out H headers);
control pipeline<H>(inout H headers, out bool accept);
@deparser control deparser<H>(packet_out b, in H headers);
package ebpfFilter<H>(parse<H> prs, pipeline<H> filt, deparser<H> dprs);
struct Headers_t {
Ethernet_h ethernet;
IPv4_h ipv4;
}

parser prs(packet_in p, out Headers_t headers) {
state start {
p.extract<Ethernet_h>(headers.ethernet);
transition select(headers.ethernet.etherType) {
16w0x800: ip;
default: reject;
}
}
state ip {
p.extract<IPv4_h>(headers.ipv4);
transition accept;
}
}

control pipe(inout Headers_t headers, out bool pass) {
@hidden action test_deparser_ebpf41() {
headers.ipv4.setInvalid();
}
@hidden action test_deparser_ebpf39() {
pass = true;
}
@hidden table tbl_test_deparser_ebpf39 {
actions = {
test_deparser_ebpf39();
}
const default_action = test_deparser_ebpf39();
}
@hidden table tbl_test_deparser_ebpf41 {
actions = {
test_deparser_ebpf41();
}
const default_action = test_deparser_ebpf41();
}
apply {
tbl_test_deparser_ebpf39.apply();
if (headers.ipv4.isValid()) {
tbl_test_deparser_ebpf41.apply();
}
}
}

control dprs(packet_out packet, in Headers_t headers) {
@hidden action test_deparser_ebpf48() {
packet.emit<Ethernet_h>(headers.ethernet);
packet.emit<IPv4_h>(headers.ipv4);
}
@hidden table tbl_test_deparser_ebpf48 {
actions = {
test_deparser_ebpf48();
}
const default_action = test_deparser_ebpf48();
}
apply {
tbl_test_deparser_ebpf48.apply();
}
}

ebpfFilter<Headers_t>(prs(), pipe(), dprs()) main;

66 changes: 66 additions & 0 deletions testdata/p4_16_samples_outputs/test_deparser_ebpf.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#include <core.p4>

@ethernetaddress typedef bit<48> EthernetAddress;
@ipv4address typedef bit<32> IPv4Address;
header Ethernet_h {
EthernetAddress dstAddr;
EthernetAddress srcAddr;
bit<16> etherType;
}

header IPv4_h {
bit<4> version;
bit<4> ihl;
bit<8> diffserv;
bit<16> totalLen;
bit<16> identification;
bit<3> flags;
bit<13> fragOffset;
bit<8> ttl;
bit<8> protocol;
bit<16> hdrChecksum;
IPv4Address srcAddr;
IPv4Address dstAddr;
}

parser parse<H>(packet_in packet, out H headers);
control pipeline<H>(inout H headers, out bool accept);
@deparser control deparser<H>(packet_out b, in H headers);
package ebpfFilter<H>(parse<H> prs, pipeline<H> filt, deparser<H> dprs);
struct Headers_t {
Ethernet_h ethernet;
IPv4_h ipv4;
}

parser prs(packet_in p, out Headers_t headers) {
state start {
p.extract(headers.ethernet);
transition select(headers.ethernet.etherType) {
16w0x800: ip;
default: reject;
}
}
state ip {
p.extract(headers.ipv4);
transition accept;
}
}

control pipe(inout Headers_t headers, out bool pass) {
apply {
pass = true;
if (headers.ipv4.isValid()) {
headers.ipv4.setInvalid();
}
}
}

control dprs(packet_out packet, in Headers_t headers) {
apply {
packet.emit(headers.ethernet);
packet.emit(headers.ipv4);
}
}

ebpfFilter(prs(), pipe(), dprs()) main;

Empty file.

0 comments on commit a5fdc50

Please sign in to comment.