Skip to content

Commit

Permalink
Modify simple_exact_example to parse ipv4 options
Browse files Browse the repository at this point in the history
Modify simple_exact_example to parse ipv4 options
Intent is to make it easier for reviewers to understand the changes
added by the previous commit
  • Loading branch information
vbnogueira committed Jun 8, 2024
1 parent d28fb85 commit c620194
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 4 deletions.
17 changes: 17 additions & 0 deletions testdata/p4tc_samples/simple_exact_example.p4
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,14 @@ header ipv4_t {
bit<32> dstAddr;
}

header v4_options_t {
varbit<320> opts;
}

struct my_ingress_headers_t {
ethernet_t ethernet;
ipv4_t ipv4;
v4_options_t opts;
}

/****** G L O B A L I N G R E S S M E T A D A T A *********/
Expand Down Expand Up @@ -64,6 +69,18 @@ parser Ingress_Parser(
}
state parse_ipv4 {
pkt.extract(hdr.ipv4);
transition select(hdr.ipv4.ihl) {
4w0: reject;
4w1: reject;
4w2: reject;
4w3: reject;
4w4: reject;
5: accept;
default: parse_v4_opts;
}
}
state parse_v4_opts {
pkt.extract(hdr.opts,(bit<32>)(32*(bit<9>)(hdr.ipv4.ihl-5)));
transition accept;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/* Automatically generated by p4c-pna-p4tc from ../testdata/p4tc_samples/simple_exact_example.p4 on Sat Jun 8 21:37:33 2024
*/
#include "simple_exact_example_parser.h"
struct p4tc_filter_fields p4tc_filter_fields;

Expand Down Expand Up @@ -64,6 +66,8 @@ static __always_inline int process(struct __sk_buff *skb, struct my_ingress_head
.tblid = 1
};
struct ingress_nh_table_key key;
// XXX eBPF gets upset at memset(); let's
// hope __builtin_memset() does what we want
__builtin_memset(&key, 0, sizeof(key));
key.keysz = 32;
key.field0 = bpf_htonl(hdr->ipv4.srcAddr);
Expand Down
117 changes: 113 additions & 4 deletions testdata/p4tc_samples_outputs/simple_exact_example_parser.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/* Automatically generated by p4c-pna-p4tc from ../testdata/p4tc_samples/simple_exact_example.p4 on Sat Jun 8 21:37:33 2024
*/
#include "simple_exact_example_parser.h"

struct p4tc_filter_fields p4tc_filter_fields;
Expand Down Expand Up @@ -30,67 +32,174 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct my_ingress_h
goto start;
parse_ipv4: {
/* extract(hdr->ipv4) */
//compileExtract
// compileExtract: dest = hdr.ipv4
// compileExtract: varsize = nil
if ((u8*)ebpf_packetEnd < hdr_start + BYTES(160 + 0)) {
ebpf_errorCode = PacketTooShort;
goto reject;
}

/* TC::PnaStateTranslationVisitor::compileExtractField: field version (fixed scalar) */
hdr->ipv4.version = (u8)((load_byte(pkt, BYTES(ebpf_packetOffsetInBits)) >> 4) & EBPF_MASK(u8, 4));
ebpf_packetOffsetInBits += 4;

/* TC::PnaStateTranslationVisitor::compileExtractField: field ihl (fixed scalar) */
hdr->ipv4.ihl = (u8)((load_byte(pkt, BYTES(ebpf_packetOffsetInBits))) & EBPF_MASK(u8, 4));
ebpf_packetOffsetInBits += 4;

/* TC::PnaStateTranslationVisitor::compileExtractField: field diffserv (fixed scalar) */
hdr->ipv4.diffserv = (u8)((load_byte(pkt, BYTES(ebpf_packetOffsetInBits))));
ebpf_packetOffsetInBits += 8;

/* TC::PnaStateTranslationVisitor::compileExtractField: field totalLen (fixed scalar) */
hdr->ipv4.totalLen = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits))));
ebpf_packetOffsetInBits += 16;

/* TC::PnaStateTranslationVisitor::compileExtractField: field identification (fixed scalar) */
hdr->ipv4.identification = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits))));
ebpf_packetOffsetInBits += 16;

/* TC::PnaStateTranslationVisitor::compileExtractField: field flags (fixed scalar) */
hdr->ipv4.flags = (u8)((load_byte(pkt, BYTES(ebpf_packetOffsetInBits)) >> 5) & EBPF_MASK(u8, 3));
ebpf_packetOffsetInBits += 3;

/* TC::PnaStateTranslationVisitor::compileExtractField: field fragOffset (fixed scalar) */
hdr->ipv4.fragOffset = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits))) & EBPF_MASK(u16, 13));
ebpf_packetOffsetInBits += 13;

/* TC::PnaStateTranslationVisitor::compileExtractField: field ttl (fixed scalar) */
hdr->ipv4.ttl = (u8)((load_byte(pkt, BYTES(ebpf_packetOffsetInBits))));
ebpf_packetOffsetInBits += 8;

/* TC::PnaStateTranslationVisitor::compileExtractField: field protocol (fixed scalar) */
hdr->ipv4.protocol = (u8)((load_byte(pkt, BYTES(ebpf_packetOffsetInBits))));
ebpf_packetOffsetInBits += 8;

/* TC::PnaStateTranslationVisitor::compileExtractField: field hdrChecksum (fixed scalar) */
hdr->ipv4.hdrChecksum = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits))));
ebpf_packetOffsetInBits += 16;

/* TC::PnaStateTranslationVisitor::compileExtractField: field srcAddr (fixed scalar) */
hdr->ipv4.srcAddr = (u32)((load_word(pkt, BYTES(ebpf_packetOffsetInBits))));
ebpf_packetOffsetInBits += 32;

/* TC::PnaStateTranslationVisitor::compileExtractField: field dstAddr (fixed scalar) */
hdr->ipv4.dstAddr = (u32)((load_word(pkt, BYTES(ebpf_packetOffsetInBits))));
ebpf_packetOffsetInBits += 32;


hdr->ipv4.ebpf_valid = 1;
hdr_start += BYTES(160);

;
u8 select_0;
select_0 = hdr->ipv4.ihl;
if (select_0 == 0)goto reject;
if (select_0 == 1)goto reject;
if (select_0 == 2)goto reject;
if (select_0 == 3)goto reject;
if (select_0 == 4)goto reject;
if (select_0 == 5)goto accept;
if ((select_0 & 0x0) == (0x0 & 0x0))goto parse_v4_opts;
else goto reject;
}
parse_v4_opts: {
/* extract(hdr->opts, (u32)(((u16)((hdr->ipv4.ihl + 11) & ((1 << 4) - 1)) << 5) & ((1 << 9) - 1))) */
//compileExtract
// compileExtract: dest = hdr.opts
// compileExtract: varsize = (bit<32>)(bit<9>)(hdr.ipv4.ihl + 11) << 5
if ((u8*)ebpf_packetEnd < hdr_start + BYTES(0 + 0)) {
ebpf_errorCode = PacketTooShort;
goto reject;
}

/* compileExtract varbit size = (u32)(((u16)((hdr->ipv4.ihl + 11) & ((1 << 4) - 1)) << 5) & ((1 << 9) - 1)) */
/* TC::PnaStateTranslationVisitor::compileExtractField: field opts (variable scalar), sizecode = (u32)(((u16)((hdr->ipv4.ihl + 11) & ((1 << 4) - 1)) << 5) & ((1 << 9) - 1)) */
{

u32 ebpf_varbits_width = (u32)(((u16)((hdr->ipv4.ihl + 11) & ((1 << 4) - 1)) << 5) & ((1 << 9) - 1));
u32 ebpf_varbits_offset;
// Can't handle this case yet
if (ebpf_varbits_width & 7) {
ebpf_errorCode = ParserInvalidArgument;
goto reject;
}
ebpf_varbits_width >>= 3;
ebpf_varbits_offset = BYTES(ebpf_packetOffsetInBits) + ebpf_varbits_width;

switch (ebpf_varbits_width)
{
case 40: hdr->opts.opts.data[39] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 39: hdr->opts.opts.data[38] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 38: hdr->opts.opts.data[37] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 37: hdr->opts.opts.data[36] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 36: hdr->opts.opts.data[35] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 35: hdr->opts.opts.data[34] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 34: hdr->opts.opts.data[33] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 33: hdr->opts.opts.data[32] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 32: hdr->opts.opts.data[31] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 31: hdr->opts.opts.data[30] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 30: hdr->opts.opts.data[29] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 29: hdr->opts.opts.data[28] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 28: hdr->opts.opts.data[27] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 27: hdr->opts.opts.data[26] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 26: hdr->opts.opts.data[25] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 25: hdr->opts.opts.data[24] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 24: hdr->opts.opts.data[23] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 23: hdr->opts.opts.data[22] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 22: hdr->opts.opts.data[21] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 21: hdr->opts.opts.data[20] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 20: hdr->opts.opts.data[19] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 19: hdr->opts.opts.data[18] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 18: hdr->opts.opts.data[17] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 17: hdr->opts.opts.data[16] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 16: hdr->opts.opts.data[15] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 15: hdr->opts.opts.data[14] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 14: hdr->opts.opts.data[13] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 13: hdr->opts.opts.data[12] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 12: hdr->opts.opts.data[11] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 11: hdr->opts.opts.data[10] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 10: hdr->opts.opts.data[9] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 9: hdr->opts.opts.data[8] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 8: hdr->opts.opts.data[7] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 7: hdr->opts.opts.data[6] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 6: hdr->opts.opts.data[5] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 5: hdr->opts.opts.data[4] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 4: hdr->opts.opts.data[3] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 3: hdr->opts.opts.data[2] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 2: hdr->opts.opts.data[1] = (u8)load_byte(pkt,--ebpf_varbits_offset);
case 1: hdr->opts.opts.data[0] = (u8)load_byte(pkt,--ebpf_varbits_offset);
}
hdr->opts.opts.curwidth = ebpf_varbits_width;
ebpf_packetOffsetInBits += ebpf_varbits_width << 3;
}

hdr->opts.ebpf_valid = 1;
hdr_start += BYTES(0);

;
goto accept;
}
start: {
/* extract(hdr->ethernet) */
//compileExtract
// compileExtract: dest = hdr.ethernet
// compileExtract: varsize = nil
if ((u8*)ebpf_packetEnd < hdr_start + BYTES(112 + 0)) {
ebpf_errorCode = PacketTooShort;
goto reject;
}

/* TC::PnaStateTranslationVisitor::compileExtractField: field dstAddr (fixed scalar) */
__builtin_memcpy(&hdr->ethernet.dstAddr, pkt + BYTES(ebpf_packetOffsetInBits), 6);
ebpf_packetOffsetInBits += 48;

/* TC::PnaStateTranslationVisitor::compileExtractField: field srcAddr (fixed scalar) */
__builtin_memcpy(&hdr->ethernet.srcAddr, pkt + BYTES(ebpf_packetOffsetInBits), 6);
ebpf_packetOffsetInBits += 48;

/* TC::PnaStateTranslationVisitor::compileExtractField: field etherType (fixed scalar) */
hdr->ethernet.etherType = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits))));
ebpf_packetOffsetInBits += 16;

Expand All @@ -99,10 +208,10 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct my_ingress_h
hdr_start += BYTES(112);

;
u16 select_0;
select_0 = hdr->ethernet.etherType;
if (select_0 == 0x800)goto parse_ipv4;
if ((select_0 & 0x0) == (0x0 & 0x0))goto reject;
u16 select_1;
select_1 = hdr->ethernet.etherType;
if (select_1 == 0x800)goto parse_ipv4;
if ((select_1 & 0x0) == (0x0 & 0x0))goto reject;
else goto reject;
}

Expand Down
7 changes: 7 additions & 0 deletions testdata/p4tc_samples_outputs/simple_exact_example_parser.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/* Automatically generated by p4c-pna-p4tc from ../testdata/p4tc_samples/simple_exact_example.p4 on Sat Jun 8 21:37:33 2024
*/
#include "ebpf_kernel.h"

#include <stdbool.h>
Expand Down Expand Up @@ -32,9 +34,14 @@ struct ipv4_t {
u32 dstAddr; /* bit<32> */
u8 ebpf_valid;
};
struct v4_options_t {
struct { u8 data[40]; u16 curwidth; } opts; /* varbit<320> */
u8 ebpf_valid;
};
struct my_ingress_headers_t {
struct ethernet_t ethernet; /* ethernet_t */
struct ipv4_t ipv4; /* ipv4_t */
struct v4_options_t opts; /* v4_options_t */
};
struct my_ingress_metadata_t {
};
Expand Down

0 comments on commit c620194

Please sign in to comment.