Skip to content

Commit

Permalink
Handle table.apply().hit correctly in ubpf backend (#3498)
Browse files Browse the repository at this point in the history
Signed-off-by: Mihai Budiu <[email protected]>
  • Loading branch information
Mihai Budiu authored Aug 30, 2022
1 parent 2fa87f5 commit f0ccf10
Show file tree
Hide file tree
Showing 9 changed files with 514 additions and 1 deletion.
15 changes: 14 additions & 1 deletion backends/ubpf/ubpfControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -429,8 +429,21 @@ namespace UBPF {
}

bool UBPFControlBodyTranslator::preorder(const IR::IfStatement *statement) {
bool isHit = P4::TableApplySolver::isHit(statement->condition, control->program->refMap,
control->program->typeMap);
if (isHit) {
// visit first the table, and then the conditional
auto member = statement->condition->to<IR::Member>();
CHECK_NULL(member);
visit(member->expr); // table application. Sets 'hitVariable'
builder->emitIndent();
}

builder->append("if (");
visit(statement->condition);
if (isHit)
builder->append(control->hitVariable);
else
visit(statement->condition);
builder->append(") ");
if (!statement->ifTrue->is<IR::BlockStatement>()) {
builder->blockStart();
Expand Down
74 changes: 74 additions & 0 deletions testdata/p4_16_samples/issue3483_ubpf.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#include <ubpf_model.p4>

#include "ebpf_headers.p4"

struct Headers_t
{
Ethernet_h ethernet;
IPv4_h ipv4;
}

struct Meta {
bit b;
}

parser prs(packet_in p, out Headers_t headers, inout Meta meta, inout standard_metadata std_meta)
{
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, inout Meta meta, inout standard_metadata unused)
{
action Reject(IPv4Address add)
{
headers.ipv4.srcAddr = add;
}

table Check_src_ip {
key = { headers.ipv4.srcAddr : exact; }
actions =
{
Reject;
NoAction;
}

default_action = NoAction;
}

apply {
if (!Check_src_ip.apply().hit) {
meta.b = 1;
}

switch (Check_src_ip.apply().action_run) {
Reject: {
meta.b = 0;
}
NoAction: {}
}
}
}

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


ubpf(prs(), pipe(), dprs()) main;
88 changes: 88 additions & 0 deletions testdata/p4_16_samples_outputs/issue3483_ubpf-first.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#include <core.p4>
#include <ubpf_model.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;
}

struct Headers_t {
Ethernet_h ethernet;
IPv4_h ipv4;
}

struct Meta {
bit<1> b;
}

parser prs(packet_in p, out Headers_t headers, inout Meta meta, inout standard_metadata std_meta) {
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, inout Meta meta, inout standard_metadata unused) {
action Reject(IPv4Address add) {
headers.ipv4.srcAddr = add;
}
table Check_src_ip {
key = {
headers.ipv4.srcAddr: exact @name("headers.ipv4.srcAddr") ;
}
actions = {
Reject();
NoAction();
}
default_action = NoAction();
}
apply {
if (Check_src_ip.apply().hit) {
;
} else {
meta.b = 1w1;
}
switch (Check_src_ip.apply().action_run) {
Reject: {
meta.b = 1w0;
}
NoAction: {
}
}
}
}

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

ubpf<Headers_t, Meta>(prs(), pipe(), dprs()) main;

90 changes: 90 additions & 0 deletions testdata/p4_16_samples_outputs/issue3483_ubpf-frontend.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#include <core.p4>
#include <ubpf_model.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;
}

struct Headers_t {
Ethernet_h ethernet;
IPv4_h ipv4;
}

struct Meta {
bit<1> b;
}

parser prs(packet_in p, out Headers_t headers, inout Meta meta, inout standard_metadata std_meta) {
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, inout Meta meta, inout standard_metadata unused) {
@noWarn("unused") @name(".NoAction") action NoAction_1() {
}
@name("pipe.Reject") action Reject(@name("add") IPv4Address add) {
headers.ipv4.srcAddr = add;
}
@name("pipe.Check_src_ip") table Check_src_ip_0 {
key = {
headers.ipv4.srcAddr: exact @name("headers.ipv4.srcAddr") ;
}
actions = {
Reject();
NoAction_1();
}
default_action = NoAction_1();
}
apply {
if (Check_src_ip_0.apply().hit) {
;
} else {
meta.b = 1w1;
}
switch (Check_src_ip_0.apply().action_run) {
Reject: {
meta.b = 1w0;
}
NoAction_1: {
}
}
}
}

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

ubpf<Headers_t, Meta>(prs(), pipe(), dprs()) main;

117 changes: 117 additions & 0 deletions testdata/p4_16_samples_outputs/issue3483_ubpf-midend.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#include <core.p4>
#include <ubpf_model.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;
}

struct Headers_t {
Ethernet_h ethernet;
IPv4_h ipv4;
}

struct Meta {
bit<1> b;
}

parser prs(packet_in p, out Headers_t headers, inout Meta meta, inout standard_metadata std_meta) {
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, inout Meta meta, inout standard_metadata unused) {
@noWarn("unused") @name(".NoAction") action NoAction_1() {
}
@name("pipe.Reject") action Reject(@name("add") IPv4Address add) {
headers.ipv4.srcAddr = add;
}
@name("pipe.Check_src_ip") table Check_src_ip_0 {
key = {
headers.ipv4.srcAddr: exact @name("headers.ipv4.srcAddr") ;
}
actions = {
Reject();
NoAction_1();
}
default_action = NoAction_1();
}
@hidden action issue3483_ubpf54() {
meta.b = 1w1;
}
@hidden action issue3483_ubpf59() {
meta.b = 1w0;
}
@hidden table tbl_issue3483_ubpf54 {
actions = {
issue3483_ubpf54();
}
const default_action = issue3483_ubpf54();
}
@hidden table tbl_issue3483_ubpf59 {
actions = {
issue3483_ubpf59();
}
const default_action = issue3483_ubpf59();
}
apply {
if (Check_src_ip_0.apply().hit) {
;
} else {
tbl_issue3483_ubpf54.apply();
}
switch (Check_src_ip_0.apply().action_run) {
Reject: {
tbl_issue3483_ubpf59.apply();
}
NoAction_1: {
}
}
}
}

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

ubpf<Headers_t, Meta>(prs(), pipe(), dprs()) main;

Loading

0 comments on commit f0ccf10

Please sign in to comment.