Skip to content

Commit

Permalink
Support of is_net_port and is_host_port externs.
Browse files Browse the repository at this point in the history
Signed-off-by: Komal Jain <[email protected]>
  • Loading branch information
komaljai committed Aug 18, 2024
1 parent 39d9d44 commit b622b48
Show file tree
Hide file tree
Showing 22 changed files with 1,691 additions and 15 deletions.
16 changes: 15 additions & 1 deletion backends/tc/ebpfCodeGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1992,14 +1992,28 @@ void ControlBodyTranslatorPNA::processMethod(const P4::ExternMethod *method) {

bool ControlBodyTranslatorPNA::preorder(const IR::AssignmentStatement *a) {
if (auto methodCallExpr = a->right->to<IR::MethodCallExpression>()) {
if (methodCallExpr->method->toString() == "is_net_port" ||
methodCallExpr->method->toString() == "is_host_port") {
builder->emitIndent();
visit(a->left);
builder->append(" = ");
if (methodCallExpr->method->toString() == "is_net_port") {
builder->append("bpf_p4tc_is_net_port(skb, ");
} else {
builder->append("bpf_p4tc_is_host_port(skb, ");
}
if (methodCallExpr->arguments->size() == 1) {
visit(methodCallExpr->arguments->at(0));
builder->append(");");
}
}
auto mi = P4::MethodInstance::resolve(methodCallExpr, control->program->refMap,
control->program->typeMap);
auto ext = mi->to<P4::ExternMethod>();
auto pnaControl = dynamic_cast<const EBPFControlPNA *>(control);
if (ext == nullptr) {
return false;
}

if (ext->originalExternType->name.name == "Register" && ext->method->type->name == "read") {
cstring name = EBPF::EBPFObject::externalName(ext->object);
auto reg = pnaControl->getRegister(name);
Expand Down
1 change: 0 additions & 1 deletion backends/tc/ebpfCodeGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,6 @@ class ControlBodyTranslatorPNA : public EBPF::ControlBodyTranslator {
const EBPF::EBPFTablePSA *table);
void processFunction(const P4::ExternFunction *function) override;
void processApply(const P4::ApplyMethod *method) override;
bool checkPnaPortMem(const IR::Member *m);
virtual cstring getParamName(const IR::PathExpression *);
bool preorder(const IR::AssignmentStatement *a) override;
void processMethod(const P4::ExternMethod *method) override;
Expand Down
21 changes: 21 additions & 0 deletions backends/tc/runtime/pna.h
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,27 @@ bpf_p4tc_ext_hash_base_16bit_complement(const void *data, const u32 data__sz,
return (base + (hash % max));
}

/* DPDK doesn't implement this yet */
/* Equivalent to PNA is_net_port */
extern bool
bpf_p4tc_is_net_port(struct __sk_buff *skb_ctx, const u32 ifindex) __ksym;

/* DPDK doesn't implement this yet */
/* Equivalent to PNA is_host_port */
extern bool
bpf_p4tc_is_host_port(struct __sk_buff *skb_ctx, const u32 ifindex) __ksym;

/* DPDK doesn't implement this yet */
/* Equivalent to PNA is_net_port */
extern bool
xdp_p4tc_is_net_port(struct xdp_md *xdp_ctx, const u32 ifindex) __ksym;

/* DPDK doesn't implement this yet */
/* Equivalent to PNA is_host_port */
extern bool
xdp_p4tc_is_host_port(struct xdp_md *xdp_ctx, const u32 ifindex) __ksym;


/* per extern specifics start */

/* in this case it is PNA so we have these helpers like below
Expand Down
4 changes: 2 additions & 2 deletions testdata/p4tc_samples/internetchecksum_01.p4
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ control ingress(
inout pna_main_output_metadata_t ostd
)
{
action set_ipip_internet_checksum(@tc_type("ipv4") bit<32> src, @tc_type("ipv4") bit<32> dst, @tc_type("dev") PortId_t port) {
action set_ipip_csum(@tc_type("ipv4") bit<32> src, @tc_type("ipv4") bit<32> dst, @tc_type("dev") PortId_t port) {
meta.src = src;
meta.dst = dst;
meta.push = true;
Expand All @@ -160,7 +160,7 @@ control ingress(
istd.input_port : exact @tc_type("dev") @name("port");
}
actions = {
set_ipip_internet_checksum;
set_ipip_csum;
set_nh;
drop;
}
Expand Down
128 changes: 128 additions & 0 deletions testdata/p4tc_samples/is_host_port.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/* -*- P4_16 -*- */

#include <core.p4>
#include <tc/pna.p4>

#define PORT_TABLE_SIZE 262144

/*
* Standard ethernet header
*/
header ethernet_t {
@tc_type ("macaddr") bit<48> dstAddr;
@tc_type ("macaddr") bit<48> srcAddr;
bit<16> etherType;
}

header ipv4_t {
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;
bit<32> srcAddr;
bit<32> dstAddr;
}

struct my_ingress_headers_t {
ethernet_t ethernet;
ipv4_t ipv4;
}

/****** G L O B A L I N G R E S S M E T A D A T A *********/

struct my_ingress_metadata_t {
}

struct empty_metadata_t {
}

/*********************** P A R S E R **************************/

parser Ingress_Parser(
packet_in pkt,
out my_ingress_headers_t hdr,
inout my_ingress_metadata_t meta,
in pna_main_parser_input_metadata_t istd)
{
const bit<16> ETHERTYPE_IPV4 = 0x0800;

state start {
transition parse_ethernet;
}
state parse_ethernet {
pkt.extract(hdr.ethernet);
transition select(hdr.ethernet.etherType) {
ETHERTYPE_IPV4 : parse_ipv4;
default : reject;
}
}
state parse_ipv4 {
pkt.extract(hdr.ipv4);
transition accept;
}
}

/***************** M A T C H - A C T I O N *********************/

control ingress(
inout my_ingress_headers_t hdr,
inout my_ingress_metadata_t meta,
in pna_main_input_metadata_t istd,
inout pna_main_output_metadata_t ostd
)
{
action send_nh(@tc_type("dev") PortId_t port_id, @tc_type("macaddr") bit<48> dmac, @tc_type("macaddr") bit<48> smac) {
hdr.ethernet.srcAddr = smac;
hdr.ethernet.dstAddr = dmac;
send_to_port(port_id);
}
action drop() {
drop_packet();
}

table nh_table {
key = {
hdr.ipv4.srcAddr : exact @tc_type ("ipv4");
}
actions = {
send_nh;
drop;
}
size = PORT_TABLE_SIZE;
const default_action = drop;
}

apply {
if (hdr.ipv4.isValid() && is_host_port(istd.input_port)) {
nh_table.apply();
}
}
}

/********************* D E P A R S E R ************************/

control Ingress_Deparser(
packet_out pkt,
inout my_ingress_headers_t hdr,
in my_ingress_metadata_t meta,
in pna_main_output_metadata_t ostd)
{
apply {
pkt.emit(hdr.ethernet);
pkt.emit(hdr.ipv4);
}
}

/************ F I N A L P A C K A G E ******************************/

PNA_NIC(
Ingress_Parser(),
ingress(),
Ingress_Deparser()
) main;
128 changes: 128 additions & 0 deletions testdata/p4tc_samples/is_net_port.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/* -*- P4_16 -*- */

#include <core.p4>
#include <tc/pna.p4>

#define PORT_TABLE_SIZE 262144

/*
* Standard ethernet header
*/
header ethernet_t {
@tc_type ("macaddr") bit<48> dstAddr;
@tc_type ("macaddr") bit<48> srcAddr;
bit<16> etherType;
}

header ipv4_t {
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;
bit<32> srcAddr;
bit<32> dstAddr;
}

struct my_ingress_headers_t {
ethernet_t ethernet;
ipv4_t ipv4;
}

/****** G L O B A L I N G R E S S M E T A D A T A *********/

struct my_ingress_metadata_t {
}

struct empty_metadata_t {
}

/*********************** P A R S E R **************************/

parser Ingress_Parser(
packet_in pkt,
out my_ingress_headers_t hdr,
inout my_ingress_metadata_t meta,
in pna_main_parser_input_metadata_t istd)
{
const bit<16> ETHERTYPE_IPV4 = 0x0800;

state start {
transition parse_ethernet;
}
state parse_ethernet {
pkt.extract(hdr.ethernet);
transition select(hdr.ethernet.etherType) {
ETHERTYPE_IPV4 : parse_ipv4;
default : reject;
}
}
state parse_ipv4 {
pkt.extract(hdr.ipv4);
transition accept;
}
}

/***************** M A T C H - A C T I O N *********************/

control ingress(
inout my_ingress_headers_t hdr,
inout my_ingress_metadata_t meta,
in pna_main_input_metadata_t istd,
inout pna_main_output_metadata_t ostd
)
{
action send_nh(@tc_type("dev") PortId_t port_id, @tc_type("macaddr") bit<48> dmac, @tc_type("macaddr") bit<48> smac) {
hdr.ethernet.srcAddr = smac;
hdr.ethernet.dstAddr = dmac;
send_to_port(port_id);
}
action drop() {
drop_packet();
}

table nh_table {
key = {
hdr.ipv4.srcAddr : exact @tc_type ("ipv4");
}
actions = {
send_nh;
drop;
}
size = PORT_TABLE_SIZE;
const default_action = drop;
}

apply {
if (hdr.ipv4.isValid() && is_net_port(istd.input_port)) {
nh_table.apply();
}
}
}

/********************* D E P A R S E R ************************/

control Ingress_Deparser(
packet_out pkt,
inout my_ingress_headers_t hdr,
in my_ingress_metadata_t meta,
in pna_main_output_metadata_t ostd)
{
apply {
pkt.emit(hdr.ethernet);
pkt.emit(hdr.ipv4);
}
}

/************ F I N A L P A C K A G E ******************************/

PNA_NIC(
Ingress_Parser(),
ingress(),
Ingress_Deparser()
) main;
2 changes: 1 addition & 1 deletion testdata/p4tc_samples_outputs/internetchecksum_01.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"actions" : [
{
"id" : 1,
"name" : "ingress/set_ipip_internet_checksum",
"name" : "ingress/set_ipip_csum",
"action_scope" : "TableAndDefault",
"annotations" : [],
"params" : [
Expand Down
6 changes: 3 additions & 3 deletions testdata/p4tc_samples_outputs/internetchecksum_01.template
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ set -e
TC="tc"
$TC p4template create pipeline/internetchecksum_01 numtables 1

$TC p4template create action/internetchecksum_01/ingress/set_ipip_internet_checksum actid 1 \
$TC p4template create action/internetchecksum_01/ingress/set_ipip_csum actid 1 \
param src type ipv4 \
param dst type ipv4 \
param port type dev
$TC p4template update action/internetchecksum_01/ingress/set_ipip_internet_checksum state active
$TC p4template update action/internetchecksum_01/ingress/set_ipip_csum state active

$TC p4template create action/internetchecksum_01/ingress/set_nh actid 2 \
param dmac type macaddr \
Expand All @@ -23,7 +23,7 @@ $TC p4template create table/internetchecksum_01/ingress/fwd_table \
tblid 1 \
type exact \
keysz 32 nummasks 8 permissions 0x3da4 tentries 1024 \
table_acts act name internetchecksum_01/ingress/set_ipip_internet_checksum \
table_acts act name internetchecksum_01/ingress/set_ipip_csum \
act name internetchecksum_01/ingress/set_nh \
act name internetchecksum_01/ingress/drop
$TC p4template update table/internetchecksum_01/ingress/fwd_table default_miss_action action internetchecksum_01/ingress/drop
Expand Down
Loading

0 comments on commit b622b48

Please sign in to comment.