Skip to content

Commit

Permalink
Add bazel support for p4c-dpdk compiler (#3441)
Browse files Browse the repository at this point in the history
1. Use 'p4c_backend' atribute to configure the p4c backend binary
used for p4_library rule. The 'p4c-dpdk' compiler can be selected
if needed. The default compiler is still 'p4c-bm2-ss'.

2. Added DPDK backend specific bf-rt-schema and context output files.

3. Added pna.p4 into default include path.

4. updated blaze example with dpdk pna program vxlan.p4.
  • Loading branch information
lzhzero authored Jul 19, 2022
1 parent be85df2 commit 5c21f41
Show file tree
Hide file tree
Showing 4 changed files with 217 additions and 8 deletions.
2 changes: 1 addition & 1 deletion BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ package(

filegroup(
name = "p4include",
srcs = glob(["p4include/*.p4"]),
srcs = glob(["p4include/**/*.p4"]),
)

genrule(
Expand Down
11 changes: 11 additions & 0 deletions bazel/example/p4/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,17 @@ p4_library(
visibility = ["//:__subpackages__"], # Optional.
)

p4_library(
name = "vxlan_dpdk_pna",
src = "vxlan.p4",
p4c_backend = "@com_github_p4lang_p4c//:p4c_dpdk",
arch = "pna",
target = "dpdk",
context_out = "vxlan.context",
bf_rt_schema_out = "vxlan.bf-rt-schema",
target_out = "vxlan.spec",
)

p4_graphs(
name = "program_graphs",
src = "program.p4",
Expand Down
178 changes: 178 additions & 0 deletions bazel/example/p4/vxlan.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
#include <core.p4>
#include <psa.p4>

struct empty_metadata_t {
}

typedef bit<48> ethernet_addr_t;

header ethernet_t {
ethernet_addr_t dst_addr;
ethernet_addr_t src_addr;
bit<16> ether_type;
}

header ipv4_t {
bit<8> ver_ihl;
bit<8> diffserv;
bit<16> total_len;
bit<16> identification;
bit<16> flags_offset;
bit<8> ttl;
bit<8> protocol;
bit<16> hdr_checksum;
bit<32> src_addr;
bit<32> dst_addr;
}

header udp_t {
bit<16> src_port;
bit<16> dst_port;
bit<16> length;
bit<16> checksum;
}

header vxlan_t {
bit<8> flags;
bit<24> reserved;
bit<24> vni;
bit<8> reserved2;
}

struct headers_t {
ethernet_t ethernet;
ipv4_t ipv4;
vxlan_t vxlan;
ethernet_t outer_ethernet;
ipv4_t outer_ipv4;
udp_t outer_udp;
vxlan_t outer_vxlan;
}

struct local_metadata_t {
ethernet_addr_t dst_addr;
ethernet_addr_t src_addr;
}

parser packet_parser(packet_in packet, out headers_t headers, inout local_metadata_t local_metadata, in psa_ingress_parser_input_metadata_t standard_metadata, in empty_metadata_t resub_meta, in empty_metadata_t recirc_meta) {
state start {
transition parse_ethernet;
}
state parse_ethernet {
packet.extract(headers.ethernet);
transition parser_ipv4;
}
state parser_ipv4 {
packet.extract(headers.ipv4);
transition accept;
}
}

control packet_deparser(packet_out packet, out empty_metadata_t clone_i2e_meta, out empty_metadata_t resubmit_meta, out empty_metadata_t normal_meta, inout headers_t headers, in local_metadata_t local_metadata, in psa_ingress_output_metadata_t istd) {
apply {
packet.emit(headers.outer_ethernet);
packet.emit(headers.outer_ipv4);
packet.emit(headers.outer_udp);
packet.emit(headers.outer_vxlan);
packet.emit(headers.ethernet);
packet.emit(headers.ipv4);
}
}

control ingress(inout headers_t headers, inout local_metadata_t local_metadata1, in psa_ingress_input_metadata_t standard_metadata, inout psa_ingress_output_metadata_t ostd) {
InternetChecksum() csum;
action vxlan_encap(
bit<48> ethernet_dst_addr,
bit<48> ethernet_src_addr,
bit<16> ethernet_ether_type,
bit<8> ipv4_ver_ihl,
bit<8> ipv4_diffserv,
bit<16> ipv4_total_len,
bit<16> ipv4_identification,
bit<16> ipv4_flags_offset,
bit<8> ipv4_ttl,
bit<8> ipv4_protocol,
bit<16> ipv4_hdr_checksum,
bit<32> ipv4_src_addr,
bit<32> ipv4_dst_addr,
bit<16> udp_src_port,
bit<16> udp_dst_port,
bit<16> udp_length,
bit<16> udp_checksum,
bit<8> vxlan_flags,
bit<24> vxlan_reserved,
bit<24> vxlan_vni,
bit<8> vxlan_reserved2,
bit<32> port_out
) {
headers.outer_ethernet.src_addr = ethernet_src_addr;
headers.outer_ethernet.dst_addr = ethernet_dst_addr;

headers.outer_ethernet.ether_type = ethernet_ether_type;
headers.outer_ipv4.ver_ihl = ipv4_ver_ihl;
headers.outer_ipv4.diffserv = ipv4_diffserv;
headers.outer_ipv4.total_len = ipv4_total_len;
headers.outer_ipv4.identification = ipv4_identification;
headers.outer_ipv4.flags_offset = ipv4_flags_offset;
headers.outer_ipv4.ttl = ipv4_ttl;
headers.outer_ipv4.protocol = ipv4_protocol;
headers.outer_ipv4.hdr_checksum = ipv4_hdr_checksum;
headers.outer_ipv4.src_addr = ipv4_src_addr;
headers.outer_ipv4.dst_addr = ipv4_dst_addr;
headers.outer_udp.src_port = udp_src_port;
headers.outer_udp.dst_port = udp_dst_port;
headers.outer_udp.length = udp_length;
headers.outer_udp.checksum = udp_checksum;
headers.vxlan.flags = vxlan_flags;
headers.vxlan.reserved = vxlan_reserved;
headers.vxlan.vni = vxlan_vni;
headers.vxlan.reserved2 = vxlan_reserved2;
ostd.egress_port = (PortId_t)port_out;
csum.add({headers.outer_ipv4.hdr_checksum, headers.ipv4.total_len});
headers.outer_ipv4.hdr_checksum = csum.get();
headers.outer_ipv4.total_len = headers.outer_ipv4.total_len + headers.ipv4.total_len;
headers.outer_udp.length = headers.outer_udp.length + headers.ipv4.total_len;
}
action drop(){
ostd.egress_port = (PortId_t)4;
}
table vxlan {
key = {
headers.ethernet.dst_addr: exact;
}
actions = {
vxlan_encap;
drop;
}
const default_action = drop;
size = 1024 * 1024;
}

apply {
vxlan.apply();
}
}


control egress(inout headers_t headers, inout local_metadata_t local_metadata, in psa_egress_input_metadata_t istd, inout psa_egress_output_metadata_t ostd) {
apply {
}
}

parser egress_parser(packet_in buffer, out headers_t headers, inout local_metadata_t local_metadata, in psa_egress_parser_input_metadata_t istd, in empty_metadata_t normal_meta, in empty_metadata_t clone_i2e_meta, in empty_metadata_t clone_e2e_meta) {
state start {
transition accept;
}
}

control egress_deparser(packet_out packet, out empty_metadata_t clone_e2e_meta, out empty_metadata_t recirculate_meta, inout headers_t headers, in local_metadata_t local_metadata, in psa_egress_output_metadata_t istd, in psa_egress_deparser_input_metadata_t edstd) {
apply {
}
}

IngressPipeline(packet_parser(), ingress(), packet_deparser()) ip;

EgressPipeline(egress_parser(), egress(), egress_deparser()) ep;

PSA_Switch(ip, PacketReplicationEngine(), ep, BufferingQueueingEngine()) main;

34 changes: 27 additions & 7 deletions bazel/p4_library.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ def _run_shell_cmd_with_p4c(ctx, command, **run_shell_kwargs):
`run_shell`.
"""

if not hasattr(ctx.executable, "_p4c"):
fail("The build rule does not specify the p4c executable via `_p4c` attribute.")
p4c = ctx.executable._p4c
if not hasattr(ctx.executable, "p4c_backend"):
fail("The build rule does not specify the p4c backend executable via `p4c_backend` attribute.")
p4c = ctx.executable.p4c_backend

cpp_toolchain = find_cpp_toolchain(ctx)
ctx.actions.run_shell(
Expand All @@ -58,7 +58,7 @@ def _run_shell_cmd_with_p4c(ctx, command, **run_shell_kwargs):
)

def _p4_library_impl(ctx):
p4c = ctx.executable._p4c
p4c = ctx.executable.p4c_backend
p4file = ctx.file.src
target = ctx.attr.target
args = _extract_common_p4c_args(ctx)
Expand All @@ -69,6 +69,18 @@ def _p4_library_impl(ctx):

outputs = []

if ctx.outputs.bf_rt_schema_out:
if target != "dpdk":
fail('Must use `target = "dpdk"` when specifying bf_rt_schema_out.')
args += ["--bf-rt-schema", ctx.outputs.bf_rt_schema_out.path]
outputs.append(ctx.outputs.bf_rt_schema_out)

if ctx.outputs.context_out:
if target != "dpdk":
fail('Must use `target = "dpdk"` when specifying context_out.')
args += ["--context", ctx.outputs.context_out.path]
outputs.append(ctx.outputs.context_out)

if ctx.outputs.p4info_out:
if target != "" and target != "bmv2":
fail('Must use `target = "bmv2"` when specifying p4info_out.')
Expand Down Expand Up @@ -112,6 +124,14 @@ p4_library = rule(
allow_files = [".p4", ".h"],
default = [],
),
"bf_rt_schema_out": attr.output(
mandatory = False,
doc = "The name of the dpdk bf rt schema output file.",
),
"context_out": attr.output(
mandatory = False,
doc = "The name of the dpdk context output file.",
),
"p4info_out": attr.output(
mandatory = False,
doc = "The name of the p4info output file.",
Expand Down Expand Up @@ -140,7 +160,7 @@ p4_library = rule(
mandatory = False,
default = "",
),
"_p4c": attr.label(
"p4c_backend": attr.label(
default = Label("@com_github_p4lang_p4c//:p4c_bmv2"),
executable = True,
cfg = "host",
Expand All @@ -156,7 +176,7 @@ p4_library = rule(
)

def _p4_graphs_impl(ctx):
p4c = ctx.executable._p4c
p4c = ctx.executable.p4c_backend
p4file = ctx.file.src
output_file = ctx.outputs.out

Expand Down Expand Up @@ -221,7 +241,7 @@ p4_graphs = rule(
mandatory = False,
default = "",
),
"_p4c": attr.label(
"p4c_backend": attr.label(
default = Label("@com_github_p4lang_p4c//:p4c_graphs"),
executable = True,
cfg = "host",
Expand Down

0 comments on commit 5c21f41

Please sign in to comment.