-
-
Notifications
You must be signed in to change notification settings - Fork 567
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2119 from ecwolf/master
Added Hello World in P4
- Loading branch information
Showing
2 changed files
with
224 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# Sample Programs in P4 | ||
|
||
Welcome to Sample Programs in P4! | ||
|
||
## Sample Programs | ||
|
||
- [Hello World in P4][0] | ||
|
||
## Fun Facts | ||
|
||
- Debut: 2013 | ||
- Developer: The P4 Language Consortium | ||
- License: Apache-style | ||
- Programming language for controlling packet forwarding planes in networking devices | ||
|
||
## References | ||
|
||
- [P4 Website][1] | ||
- [P4 GitHub][2] | ||
|
||
[0]: https://github.com/TheRenegadeCoder/sample-programs/issues/2117 | ||
[1]: https://p4.org/code/ | ||
[2]: https://github.com/p4lang/p4c |
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,201 @@ | ||
/* -*- P4_16 -*- */ | ||
|
||
|
||
|
||
/************************************************************************* | ||
This is a P4 "Hello World" code: | ||
When a packet arrives to the switch with some payload | ||
data of 88 bites, the switch will forward the packet | ||
changing the payload to "Hello World". | ||
The program is not intended to calculate a new checksum, | ||
many errors can occur avoiding that process. | ||
@ecwolf | ||
*************************************************************************/ | ||
|
||
|
||
#include <core.p4> | ||
#include <v1model.p4> | ||
|
||
const bit<16> TYPE_IPV4 = 0x800; | ||
const bit<8> UDP_TYPE = 0x11; | ||
const bit<8> TCP_TYPE = 0x06; | ||
|
||
/************************************************************************* | ||
*********************** H E A D E R S *********************************** | ||
*************************************************************************/ | ||
|
||
typedef bit<9> egressSpec_t; | ||
typedef bit<48> macAddr_t; | ||
typedef bit<32> ip4Addr_t; | ||
|
||
header ethernet_t { | ||
macAddr_t dstAddr; | ||
macAddr_t 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; | ||
ip4Addr_t srcAddr; | ||
ip4Addr_t dstAddr; | ||
} | ||
|
||
header udp_t | ||
{ | ||
bit<16> srcPort; | ||
bit<16> dstPort; | ||
bit<16> len; | ||
bit<16> checksum; | ||
bit<88> payload; | ||
} | ||
|
||
struct metadata { | ||
/* empty */ | ||
} | ||
|
||
struct headers { | ||
ethernet_t ethernet; | ||
ipv4_t ipv4; | ||
udp_t udp; | ||
} | ||
|
||
/************************************************************************* | ||
*********************** P A R S E R *********************************** | ||
*************************************************************************/ | ||
|
||
parser MyParser(packet_in packet, | ||
out headers hdr, | ||
inout metadata meta, | ||
inout standard_metadata_t standard_metadata) { | ||
|
||
state start { | ||
transition parse_ethernet; | ||
} | ||
|
||
state parse_ethernet { | ||
packet.extract(hdr.ethernet); | ||
transition select(hdr.ethernet.etherType) { | ||
TYPE_IPV4: parse_ipv4; | ||
default: accept; | ||
} | ||
} | ||
|
||
state parse_ipv4 { | ||
packet.extract(hdr.ipv4); | ||
transition select(hdr.ipv4.protocol) { | ||
UDP_TYPE : parse_udp; | ||
default : accept; | ||
} | ||
} | ||
|
||
state parse_udp { | ||
packet.extract(hdr.udp); | ||
transition accept; | ||
|
||
} | ||
|
||
|
||
} | ||
|
||
/************************************************************************* | ||
************ C H E C K S U M V E R I F I C A T I O N ************* | ||
*************************************************************************/ | ||
|
||
control MyVerifyChecksum(inout headers hdr, inout metadata meta) { | ||
apply { } | ||
} | ||
|
||
/************************************************************************* | ||
************** I N G R E S S P R O C E S S I N G ******************* | ||
*************************************************************************/ | ||
|
||
control MyIngress(inout headers hdr, | ||
inout metadata meta, | ||
inout standard_metadata_t standard_metadata) { | ||
|
||
action drop() { | ||
mark_to_drop(standard_metadata); | ||
} | ||
|
||
action ipv4_forward(macAddr_t dstAddr, egressSpec_t port) { | ||
standard_metadata.egress_spec = port; | ||
hdr.ethernet.srcAddr = hdr.ethernet.dstAddr; | ||
hdr.ethernet.dstAddr = dstAddr; | ||
hdr.ipv4.ttl = hdr.ipv4.ttl - 1; | ||
hdr.udp.payload = 0x48656C6C6F20576F726C64; // payload='Hello World' | ||
} | ||
|
||
table ipv4_lpm { | ||
key = { | ||
hdr.ipv4.dstAddr: lpm; | ||
} | ||
actions = { | ||
ipv4_forward; | ||
drop; | ||
NoAction; | ||
} | ||
size = 1024; | ||
default_action = drop(); | ||
} | ||
|
||
apply { | ||
ipv4_lpm.apply(); | ||
} | ||
} | ||
|
||
/************************************************************************* | ||
**************** E G R E S S P R O C E S S I N G ******************* | ||
*************************************************************************/ | ||
|
||
control MyEgress(inout headers hdr, | ||
inout metadata meta, | ||
inout standard_metadata_t standard_metadata) { | ||
apply {} | ||
} | ||
|
||
/************************************************************************* | ||
************* C H E C K S U M C O M P U T A T I O N ************** | ||
*************************************************************************/ | ||
|
||
control MyComputeChecksum(inout headers hdr, inout metadata meta) { | ||
apply {} | ||
} | ||
|
||
/************************************************************************* | ||
*********************** D E P A R S E R ******************************* | ||
*************************************************************************/ | ||
|
||
control MyDeparser(packet_out packet, in headers hdr) { | ||
apply { | ||
packet.emit(hdr.ethernet); | ||
packet.emit(hdr.ipv4); | ||
packet.emit(hdr.udp); | ||
} | ||
} | ||
|
||
/************************************************************************* | ||
*********************** S W I T C H ******************************* | ||
*************************************************************************/ | ||
|
||
V1Switch( | ||
MyParser(), | ||
MyVerifyChecksum(), | ||
MyIngress(), | ||
MyEgress(), | ||
MyComputeChecksum(), | ||
MyDeparser() | ||
) main; |