-
Notifications
You must be signed in to change notification settings - Fork 446
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Victor Nogueira <victor@mojatatu.com>
- Loading branch information
1 parent
0c3408b
commit e5ba246
Showing
8 changed files
with
997 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,239 @@ | ||
/* -*- P4_16 -*- */ | ||
|
||
/* | ||
* P4 Calculator | ||
* | ||
* This program implements a simple protocol. It can be carried over Ethernet | ||
* (Ethertype 0x1234). | ||
* | ||
* The Protocol header looks like this: | ||
* | ||
* 0 1 2 3 | ||
* +----------------+----------------+----------------+---------------+ | ||
* | P | 4 | Version | Op | | ||
* +----------------+----------------+----------------+---------------+ | ||
* | Operand A | | ||
* +----------------+----------------+----------------+---------------+ | ||
* | Operand B | | ||
* +----------------+----------------+----------------+---------------+ | ||
* | Result | | ||
* +----------------+----------------+----------------+---------------+ | ||
* | ||
* P is an ASCII Letter 'P' (0x50) | ||
* 4 is an ASCII Letter '4' (0x34) | ||
* Version is currently 0.1 (0x01) | ||
* Op is an operation to Perform: | ||
* '+' (0x2b) Result = OperandA + OperandB | ||
* '-' (0x2d) Result = OperandA - OperandB | ||
* '&' (0x26) Result = OperandA & OperandB | ||
* '|' (0x7c) Result = OperandA | OperandB | ||
* '^' (0x5e) Result = OperandA ^ OperandB | ||
* | ||
* The device receives a packet, performs the requested operation, fills in the | ||
* result and sends the packet back out of the same port it came in on, while | ||
* swapping the source and destination addresses. | ||
* | ||
* If an unknown operation is specified or the header is not valid, the packet | ||
* is dropped | ||
*/ | ||
|
||
#include <core.p4> | ||
#include <tc/pna.p4> | ||
|
||
|
||
/* | ||
* Define the headers the program will recognize | ||
*/ | ||
|
||
/* | ||
* Standard ethernet header | ||
*/ | ||
header ethernet_t { | ||
bit<48> dstAddr; | ||
bit<48> srcAddr; | ||
bit<16> etherType; | ||
} | ||
|
||
/* | ||
* This is a custom protocol header for the calculator. We'll use | ||
* ethertype 0x1234 for is (see parser) | ||
*/ | ||
const bit<16> P4CALC_ETYPE = 0x1234; | ||
const bit<8> P4CALC_P = 0x50; // 'P' | ||
const bit<8> P4CALC_4 = 0x34; // '4' | ||
const bit<8> P4CALC_VER = 0x01; // v0.1 | ||
const bit<8> P4CALC_PLUS = 0x2b; // '+' | ||
const bit<8> P4CALC_MINUS = 0x2d; // '-' | ||
const bit<8> P4CALC_AND = 0x26; // '&' | ||
const bit<8> P4CALC_OR = 0x7c; // '|' | ||
const bit<8> P4CALC_CARET = 0x5e; // '^' | ||
|
||
header p4calc_t { | ||
bit<8> p; | ||
bit<8> four; | ||
bit<8> ver; | ||
bit<8> op; | ||
bit<32> operand_a; | ||
bit<32> operand_b; | ||
bit<32> res; | ||
} | ||
|
||
/* | ||
* All headers, used in the program needs to be assembed into a single struct. | ||
* We only need to declare the type, but there is no need to instantiate it, | ||
* because it is done "by the architecture", i.e. outside of P4 functions | ||
*/ | ||
struct headers_t { | ||
ethernet_t ethernet; | ||
p4calc_t p4calc; | ||
} | ||
|
||
/* | ||
* All metadata, globally used in the program, also needs to be assembed | ||
* into a single struct. As in the case of the headers, we only need to | ||
* declare the type, but there is no need to instantiate it, | ||
* because it is done "by the architecture", i.e. outside of P4 functions | ||
*/ | ||
|
||
struct metadata_t { | ||
/* In our case it is empty */ | ||
} | ||
|
||
/************************************************************************* | ||
*********************** P A R S E R *********************************** | ||
*************************************************************************/ | ||
parser MainParserImpl( | ||
packet_in pkt, | ||
out headers_t hdr, | ||
inout metadata_t meta, | ||
in pna_main_parser_input_metadata_t istd) | ||
{ | ||
|
||
state start { | ||
pkt.extract(hdr.ethernet); | ||
transition select(hdr.ethernet.etherType) { | ||
P4CALC_ETYPE : check_p4calc; | ||
default : accept; | ||
} | ||
} | ||
|
||
state check_p4calc { | ||
transition select(pkt.lookahead<p4calc_t>().p, | ||
pkt.lookahead<p4calc_t>().four, | ||
pkt.lookahead<p4calc_t>().ver) { | ||
(P4CALC_P, P4CALC_4, P4CALC_VER) : parse_p4calc; | ||
default : accept; | ||
} | ||
} | ||
|
||
state parse_p4calc { | ||
pkt.extract(hdr.p4calc); | ||
transition accept; | ||
} | ||
} | ||
|
||
|
||
/************************************************************************* | ||
********************** M A I N C O N T R O L ************************ | ||
*************************************************************************/ | ||
control MainControlImpl( | ||
inout headers_t hdr, | ||
inout metadata_t meta, | ||
in pna_main_input_metadata_t istd, | ||
inout pna_main_output_metadata_t ostd) | ||
{ | ||
|
||
action send_back(bit<32> result) { | ||
bit<48> tmp; | ||
|
||
/* Put the result back in */ | ||
hdr.p4calc.res = result; | ||
|
||
/* Swap the MAC addresses */ | ||
tmp = hdr.ethernet.dstAddr; | ||
hdr.ethernet.dstAddr = hdr.ethernet.srcAddr; | ||
hdr.ethernet.srcAddr = tmp; | ||
/* Send the packet back to the port it came from */ | ||
send_to_port(istd.input_port); | ||
} | ||
|
||
action operation_add() { | ||
send_back(hdr.p4calc.operand_a + hdr.p4calc.operand_b); | ||
} | ||
|
||
action operation_sub() { | ||
send_back(hdr.p4calc.operand_a - hdr.p4calc.operand_b); | ||
} | ||
|
||
action operation_and() { | ||
send_back(hdr.p4calc.operand_a & hdr.p4calc.operand_b); | ||
} | ||
|
||
action operation_or() { | ||
send_back(hdr.p4calc.operand_a | hdr.p4calc.operand_b); | ||
} | ||
|
||
action operation_xor() { | ||
send_back(hdr.p4calc.operand_a ^ hdr.p4calc.operand_b); | ||
} | ||
|
||
action operation_drop() { | ||
drop_packet(); | ||
} | ||
|
||
table calculate { | ||
key = { | ||
hdr.p4calc.op : exact @name("op"); | ||
} | ||
actions = { | ||
operation_add; | ||
operation_sub; | ||
operation_and; | ||
operation_or; | ||
operation_xor; | ||
operation_drop; | ||
} | ||
const default_action = operation_drop(); | ||
const entries = { | ||
P4CALC_PLUS : operation_add(); | ||
P4CALC_MINUS: operation_sub(); | ||
P4CALC_AND : operation_and(); | ||
P4CALC_OR : operation_or(); | ||
P4CALC_CARET: operation_xor(); | ||
} | ||
} | ||
|
||
|
||
apply { | ||
if (hdr.p4calc.isValid()) { | ||
calculate.apply(); | ||
} else { | ||
operation_drop(); | ||
} | ||
} | ||
} | ||
|
||
|
||
/************************************************************************* | ||
*********************** D E P A R S E R ******************************* | ||
*************************************************************************/ | ||
control MainDeparserImpl( | ||
packet_out pkt, | ||
inout headers_t hdr, | ||
in metadata_t meta, | ||
in pna_main_output_metadata_t ostd) | ||
{ | ||
apply { | ||
pkt.emit(hdr.ethernet); | ||
pkt.emit(hdr.p4calc); | ||
} | ||
} | ||
|
||
/************************************************************************* | ||
****************************** P N A ********************************** | ||
*************************************************************************/ | ||
PNA_NIC( | ||
MainParserImpl(), | ||
MainControlImpl(), | ||
MainDeparserImpl() | ||
) main; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
packet 0 10000002 aabb1000 0001aabb 12345034 012b0000 00010000 00020000 000020 | ||
expect 0 10000001 aabb1000 0002aabb 12345034 012b0000 00010000 00020000 000320 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
{ | ||
"schema_version" : "1.0.0", | ||
"pipeline_name" : "calculator", | ||
"externs" : [], | ||
"tables" : [ | ||
{ | ||
"name" : "MainControlImpl/calculate", | ||
"id" : 1, | ||
"tentries" : 1024, | ||
"permissions" : "0x3da4", | ||
"nummask" : 8, | ||
"keysize" : 8, | ||
"keyfields" : [ | ||
{ | ||
"id" : 1, | ||
"name" : "op", | ||
"type" : "bit8", | ||
"match_type" : "exact", | ||
"bitwidth" : 8 | ||
} | ||
], | ||
"actions" : [ | ||
{ | ||
"id" : 1, | ||
"name" : "MainControlImpl/operation_add", | ||
"action_scope" : "TableAndDefault", | ||
"annotations" : [], | ||
"params" : [], | ||
"default_hit_action" : false, | ||
"default_miss_action" : false | ||
}, | ||
{ | ||
"id" : 2, | ||
"name" : "MainControlImpl/operation_sub", | ||
"action_scope" : "TableAndDefault", | ||
"annotations" : [], | ||
"params" : [], | ||
"default_hit_action" : false, | ||
"default_miss_action" : false | ||
}, | ||
{ | ||
"id" : 3, | ||
"name" : "MainControlImpl/operation_and", | ||
"action_scope" : "TableAndDefault", | ||
"annotations" : [], | ||
"params" : [], | ||
"default_hit_action" : false, | ||
"default_miss_action" : false | ||
}, | ||
{ | ||
"id" : 4, | ||
"name" : "MainControlImpl/operation_or", | ||
"action_scope" : "TableAndDefault", | ||
"annotations" : [], | ||
"params" : [], | ||
"default_hit_action" : false, | ||
"default_miss_action" : false | ||
}, | ||
{ | ||
"id" : 5, | ||
"name" : "MainControlImpl/operation_xor", | ||
"action_scope" : "TableAndDefault", | ||
"annotations" : [], | ||
"params" : [], | ||
"default_hit_action" : false, | ||
"default_miss_action" : false | ||
}, | ||
{ | ||
"id" : 6, | ||
"name" : "MainControlImpl/operation_drop", | ||
"action_scope" : "TableAndDefault", | ||
"annotations" : [], | ||
"params" : [], | ||
"default_hit_action" : false, | ||
"default_miss_action" : true | ||
} | ||
] | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
#!/bin/bash -x | ||
|
||
set -e | ||
|
||
: "${TC:="tc"}" | ||
$TC p4template create pipeline/calculator numtables 1 | ||
|
||
$TC p4template create action/calculator/MainControlImpl/operation_add actid 1 | ||
$TC p4template update action/calculator/MainControlImpl/operation_add state active | ||
|
||
$TC p4template create action/calculator/MainControlImpl/operation_sub actid 2 | ||
$TC p4template update action/calculator/MainControlImpl/operation_sub state active | ||
|
||
$TC p4template create action/calculator/MainControlImpl/operation_and actid 3 | ||
$TC p4template update action/calculator/MainControlImpl/operation_and state active | ||
|
||
$TC p4template create action/calculator/MainControlImpl/operation_or actid 4 | ||
$TC p4template update action/calculator/MainControlImpl/operation_or state active | ||
|
||
$TC p4template create action/calculator/MainControlImpl/operation_xor actid 5 | ||
$TC p4template update action/calculator/MainControlImpl/operation_xor state active | ||
|
||
$TC p4template create action/calculator/MainControlImpl/operation_drop actid 6 | ||
$TC p4template update action/calculator/MainControlImpl/operation_drop state active | ||
|
||
$TC p4template create table/calculator/MainControlImpl/calculate \ | ||
tblid 1 \ | ||
type exact \ | ||
keysz 8 permissions 0x3da4 tentries 1024 nummasks 1 \ | ||
table_acts act name calculator/MainControlImpl/operation_add \ | ||
act name calculator/MainControlImpl/operation_sub \ | ||
act name calculator/MainControlImpl/operation_and \ | ||
act name calculator/MainControlImpl/operation_or \ | ||
act name calculator/MainControlImpl/operation_xor \ | ||
act name calculator/MainControlImpl/operation_drop | ||
$TC p4template update table/calculator/MainControlImpl/calculate default_miss_action permissions 0x1024 action calculator/MainControlImpl/operation_drop | ||
$TC p4template create table/calculator/MainControlImpl/calculate entry op 0x2b permissions 0x1024 action calculator/MainControlImpl/operation_add | ||
$TC p4template create table/calculator/MainControlImpl/calculate entry op 0x2d permissions 0x1024 action calculator/MainControlImpl/operation_sub | ||
$TC p4template create table/calculator/MainControlImpl/calculate entry op 0x26 permissions 0x1024 action calculator/MainControlImpl/operation_and | ||
$TC p4template create table/calculator/MainControlImpl/calculate entry op 0x7c permissions 0x1024 action calculator/MainControlImpl/operation_or | ||
$TC p4template create table/calculator/MainControlImpl/calculate entry op 0x5e permissions 0x1024 action calculator/MainControlImpl/operation_xor | ||
$TC p4template update pipeline/calculator state ready |
Oops, something went wrong.