diff --git a/p4-cheat-sheet.pdf b/p4-cheat-sheet.pdf new file mode 100644 index 0000000..d6eae7f Binary files /dev/null and b/p4-cheat-sheet.pdf differ diff --git a/utils/cheat_sheet_src/main.tex b/utils/cheat_sheet_src/main.tex new file mode 100644 index 0000000..f9db04c --- /dev/null +++ b/utils/cheat_sheet_src/main.tex @@ -0,0 +1,220 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% P4 Cheat Sheet +% +% By P4.org +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\documentclass{article} + +\usepackage{fontspec} +\setmainfont{Utopia} +\setsansfont{Free Helvetian} +\setmonofont{Liberation Mono} + +\usepackage[landscape]{geometry} +\usepackage{url} +\usepackage{multicol} +\usepackage{amsmath} +\usepackage{amsfonts} +\usepackage{tikz} +\usetikzlibrary{shapes} +\usetikzlibrary{decorations.pathmorphing} +\usepackage{amsmath,amssymb} + +\usepackage{colortbl} +\usepackage{xcolor} +\usepackage{mathtools} +\usepackage{amsmath,amssymb} +\usepackage{enumitem} + +% Define Colors +\usepackage{color} +\definecolor{eclipseBlue}{RGB}{42,0.0,255} +\definecolor{eclipseGreen}{RGB}{63,127,95} +\definecolor{eclipsePurple}{RGB}{127,0,85} + +\usepackage{listings} + +% Define Language +\lstdefinelanguage{p4} +{ + % list of keywords + morekeywords={ + action, apply, bit, bool, const, control, default, else, enum, error, extern, exit, false, header, if, in, inout, int, match_kind, package, parser, out, return, select, state, struct, switch, table, transition, true, tuple, typedef, varbit, verify, void, + }, + sensitive=true, % keywords are case-sensitive + morecomment=[l]{//}, % l is for line comment + morecomment=[s]{/*}{*/}, % s is for start and end delimiter + morestring=[b]" % defines that strings are enclosed in double quotes +} + +% Set Language +\lstset{ + language={p4}, + basicstyle=\small\ttfamily, % Global Code Style + captionpos=b, % Position of the Caption (t for top, b for bottom) + extendedchars=true, % Allows 256 instead of 128 ASCII characters + tabsize=2, % number of spaces indented when discovering a tab + columns=fixed, % make all characters equal width + keepspaces=true, % does not ignore spaces to fit width, convert tabs to spaces + showstringspaces=false, % lets spaces in strings appear as real spaces + breaklines=true, % wrap lines if they don't fit + commentstyle=\color{eclipseBlue}, % style of comments + keywordstyle=\color{eclipsePurple}, % style of keywords + stringstyle=\color{eclipseGreen}, % style of strings +} + +\title{P4 Cheat Sheet} +\usepackage[brazilian]{babel} + +\advance\topmargin-.8in +\advance\textheight3in +\advance\textwidth3in +\advance\oddsidemargin-1.5in +\advance\evensidemargin-1.5in +\parindent0pt +\parskip2pt +\newcommand{\hr}{\centerline{\rule{3.5in}{1pt}}} +%\colorbox[HTML]{e4e4e4}{\makebox[\textwidth-2\fboxsep][l]{texto} +\begin{document} + +\begin{center}{\huge{\bf \textsf{P4 Language Cheat Sheet}}}\\[.5em] +%{\large By P4.org} +\end{center} +\begin{multicols*}{3} + +\tikzstyle{mybox} = [draw=black, fill=white, very thick, + rectangle, rounded corners, inner sep=10pt, inner ysep=10pt] +\tikzstyle{fancytitle} =[fill=black, text=white, font=\bfseries] +\tikzstyle{mybox2} = [draw=black, fill=white, very thick, rectangle split, + rectangle split parts=2, + rounded corners, inner sep=10pt, inner ysep=10pt] +\tikzstyle{fancytitle2} =[fill=black, text=white, font=\bfseries] + +%------------ DATA TYPES --------------- +\begin{tikzpicture} +\node [mybox] (box){% + \begin{minipage}{0.3\textwidth} + \lstinputlisting{src/data_types.txt} + \end{minipage} +}; +\node[fancytitle, right=10pt] at (box.north west) {Basic Data Types}; +\end{tikzpicture} + +%------------ P4 Parsing --------------- +\begin{tikzpicture} +\node [mybox] (box){% + \begin{minipage}{0.3\textwidth} + \lstinputlisting{src/parsers.txt} + \end{minipage} +}; +\node[fancytitle, right=10pt] at (box.north west) {Parsing}; +\end{tikzpicture} + +%------------ Expressions --------------------- +\begin{tikzpicture} +\node [mybox] (box){% + \begin{minipage}{0.3\textwidth} + \lstinputlisting{src/expressions.txt} + \end{minipage} +}; +\node[fancytitle, right=10pt] at (box.north west) {Statements \& Expressions}; +\end{tikzpicture} + +%------------ Actions --------------------- +\begin{tikzpicture} +\node [mybox] (box){% + \begin{minipage}{0.3\textwidth} + \lstinputlisting{src/actions.txt} + \end{minipage} +}; +\node[fancytitle, right=10pt] at (box.north west) {Actions}; +\end{tikzpicture} + +%------------ Tables --------------------- +\begin{tikzpicture} +\node [mybox] (box){% + \begin{minipage}{0.3\textwidth} + \lstinputlisting{src/tables.txt} + \end{minipage} +}; +\node[fancytitle, right=10pt] at (box.north west) {Tables}; +\end{tikzpicture} + +%------------ Control Flow --------------------- +\begin{tikzpicture} +\node [mybox] (box){% + \begin{minipage}{0.3\textwidth} + \lstinputlisting{src/control_flow.txt} + \end{minipage} +}; +\node[fancytitle, right=10pt] at (box.north west) {Control Flow}; +\end{tikzpicture} + +%------------ Deparsing --------------------- +\begin{tikzpicture} +\node [mybox] (box){% + \begin{minipage}{0.3\textwidth} + \lstinputlisting{src/deparsing.txt} + \end{minipage} +}; +\node[fancytitle, right=10pt] at (box.north west) {Deparsing}; +\end{tikzpicture} + +%------------ Header Stacks --------------------- +\begin{tikzpicture} +\node [mybox] (box){% + \begin{minipage}{0.3\textwidth} + \lstinputlisting{src/header_stack.txt} + \end{minipage} +}; +\node[fancytitle, right=10pt] at (box.north west) {Header Stacks}; +\end{tikzpicture} + +%------------ Advanced Parsing --------------------- +\begin{tikzpicture} +\node [mybox] (box){% + \begin{minipage}{0.3\textwidth} + \lstinputlisting{src/adv_parsing.txt} + \end{minipage} +}; +\node[fancytitle, right=10pt] at (box.north west) {Advanced Parsing}; +\end{tikzpicture} + +%------------ V1Model - Architecture --------------------- +\begin{tikzpicture} +\node [mybox] (box){% + \begin{minipage}{0.3\textwidth} + \lstinputlisting{src/architecture.txt} + \end{minipage} +}; +\node[fancytitle, right=10pt] at (box.north west) {V1Model - Architecture}; +\end{tikzpicture} + +%------------ V1Model - Standard Metadata --------------------- +\begin{tikzpicture} +\node [mybox] (box){% + \begin{minipage}{0.3\textwidth} + \lstinputlisting{src/v1model_std_metadata.txt} + \end{minipage} +}; +\node[fancytitle, right=10pt] at (box.north west) {V1Model - Standard Metadata}; +\end{tikzpicture} + +%------------ V1Model - Counter Externs --------------------- +\begin{tikzpicture} +\node [mybox] (box){% + \begin{minipage}{0.3\textwidth} + \lstinputlisting{src/counters.txt} + \end{minipage} +}; +\node[fancytitle, right=10pt] at (box.north west) {V1Model - Counters \& Registers}; +\end{tikzpicture} + + + +\end{multicols*} +\end{document} +Contact GitHub API Training Shop Blog About +© 2016 GitHub, Inc. Terms Privacy Security Status Help \ No newline at end of file diff --git a/utils/cheat_sheet_src/src/actions.txt b/utils/cheat_sheet_src/src/actions.txt new file mode 100644 index 0000000..63801a7 --- /dev/null +++ b/utils/cheat_sheet_src/src/actions.txt @@ -0,0 +1,28 @@ +// Inputs provided by control-plane +action set_next_hop(bit<32> next_hop) { + if (next_hop == 0) { + metadata.next_hop = hdr.ipv4.dst; + } else { + metadata.next_hop = next_hop; + } +} + +// Inputs provided by data-plane +action swap_mac(inout bit<48> x, + inout bit<48> y) { + bit<48> tmp = x; + x = y; + y = tmp; +} + +// Inputs provided by control/data-plane +action forward(in bit<9> p, bit<48> d) { + standard_metadata.egress_spec = p; + headers.ethernet.dstAddr = d; +} + +// Remove header from packet +action decap_ip_ip() { + hdr.ipv4 = hdr.inner_ipv4; + hdr.inner_ipv4.setInvalid(); +} diff --git a/utils/cheat_sheet_src/src/adv_parsing.txt b/utils/cheat_sheet_src/src/adv_parsing.txt new file mode 100644 index 0000000..2b1167b --- /dev/null +++ b/utils/cheat_sheet_src/src/adv_parsing.txt @@ -0,0 +1,23 @@ +// common defns for IPv4 and IPv6 +header ip46_t { + bit<4> version; + bit<4> reserved; +} + +// header stack parsing +state parse_labels { + packet.extract(hdr.labels.next); + transition select(hdr.labels.last.bos) { + 0: parse_labels; // create loop + 1: guess_labels_payload; + } +} + +// lookahead parsing +state guess_labels_payload { + transition select(packet.lookahead().version) { + 4 : parse_inner_ipv4; + 6 : parse_inner_ipv6; + default : parse_inner_ethernet; + } +} diff --git a/utils/cheat_sheet_src/src/architecture.txt b/utils/cheat_sheet_src/src/architecture.txt new file mode 100644 index 0000000..5fb4010 --- /dev/null +++ b/utils/cheat_sheet_src/src/architecture.txt @@ -0,0 +1,46 @@ +// common externs +extern void truncate(in bit<32> length); +extern void resubmit(in T x); +extern void recirculate(in T x); +enum CloneType { I2E, E2I } +extern void clone(in CloneType type, + in bit<32> session); + +// v1model pipeline elements +parser Parser( + packet_in pkt, + out H hdr, + inout M meta, + inout standard_metadata_t std_meta +); +control VerifyChecksum( + inout H hdr, + inout M meta +); +control Ingress( + inout H hdr, + inout M meta, + inout standard_metadata_t std_meta +); +control Egress( + inout H hdr, + inout M meta, + inout standard_metadata_t std_meta +); +control ComputeChecksum( + inout H hdr, + inout M meta +); +control Deparser( + packet_out b, in H hdr +); + +// v1model switch +package V1Switch( + Parser p, + VerifyChecksum vr, + Ingress ig, + Egress eg, + ComputeChecksum ck, + Deparser d +); diff --git a/utils/cheat_sheet_src/src/control_flow.txt b/utils/cheat_sheet_src/src/control_flow.txt new file mode 100644 index 0000000..95d83e2 --- /dev/null +++ b/utils/cheat_sheet_src/src/control_flow.txt @@ -0,0 +1,15 @@ +apply { + // branch on header validity + if (hdr.ipv4.isValid()) { + ipv4_lpm.apply(); + } + // branch on table hit result + if (local_ip_table.apply().hit) { + send_to_cpu(); + } + // branch on table action invocation + switch (table1.apply().action_run) { + action1: { table2.apply(); } + action2: { table3.apply(); } + } +} \ No newline at end of file diff --git a/utils/cheat_sheet_src/src/counters.txt b/utils/cheat_sheet_src/src/counters.txt new file mode 100644 index 0000000..1583eea --- /dev/null +++ b/utils/cheat_sheet_src/src/counters.txt @@ -0,0 +1,19 @@ +// counters +counter(8192, CounterType.packets) c; + +action count(bit<32> index) { + //increment counter at index + c.count(index); +} + +// registers +register>(16384) r; + +action ipg(out bit<48> ival, bit<32> x) { + bit<48> last; + bit<48> now; + r.read(last, x); + now = std_meta.ingress_global_timestamp; + ival = now - last; + r.write(x, now); +} diff --git a/utils/cheat_sheet_src/src/data_types.txt b/utils/cheat_sheet_src/src/data_types.txt new file mode 100644 index 0000000..7029d02 --- /dev/null +++ b/utils/cheat_sheet_src/src/data_types.txt @@ -0,0 +1,22 @@ +// typedef: introduces alternate type name +typedef bit<48> macAddr_t; +typedef bit<32> ip4Addr_t; + +// headers: ordered collection of members +// operations test and set validity bits: +// isValid(), setValid(), setInvalid() +header ethernet_t { + macAddr_t dstAddr; + macAddr_t srcAddr; + bit<16> type; +} + +// variable declaration and member access +ethernet_t ethernet; +macAddr_t src = ethernet.srcAddr; + +// struct: unordered collection of members +struct headers_t { + ethernet_t ethernet; +} + diff --git a/utils/cheat_sheet_src/src/deparsing.txt b/utils/cheat_sheet_src/src/deparsing.txt new file mode 100644 index 0000000..f6468dc --- /dev/null +++ b/utils/cheat_sheet_src/src/deparsing.txt @@ -0,0 +1,9 @@ +// packet_out: extern for output packet +extern packet_out { + void emit(in T hdr); +} + +apply { + // insert headers into pkt if valid + packet.emit(hdr.ethernet); +} \ No newline at end of file diff --git a/utils/cheat_sheet_src/src/expressions.txt b/utils/cheat_sheet_src/src/expressions.txt new file mode 100644 index 0000000..5c1688d --- /dev/null +++ b/utils/cheat_sheet_src/src/expressions.txt @@ -0,0 +1,13 @@ +// Local metadata declaration, assignment +bit<16> tmp1; bit<16> tmp2; +tmp1 = hdr.ethernet.type; + +// bit slicing, concatenation +tmp2 = tmp1[7:0] ++ tmp1[15:8]; + +// addition, subtraction, casts +tmp2 = tmp1 + tmp1 - (bit<16>)tmp1[7:0]; + +// bitwise operators +tmp2 = (~tmp1 & tmp1) | (tmp1 ^ tmp1); +tmp2 = tmp1 << 3; \ No newline at end of file diff --git a/utils/cheat_sheet_src/src/header_stack.txt b/utils/cheat_sheet_src/src/header_stack.txt new file mode 100644 index 0000000..85328f9 --- /dev/null +++ b/utils/cheat_sheet_src/src/header_stack.txt @@ -0,0 +1,21 @@ +// header stack declaration +header label_t { + bit<20> label; + bit bos; +} +struct header_t { + label_t[10] labels; +} +header_t hdr; + +// remove from header stack +action pop_label() { + hdr.labels.pop_front(1); +} + +// add to header stack +action push_label(in bit<20> label) { + hdr.labels.push_front(1); + hdr.labels[0].setValid(); + hdr.labels[0] = { label, 0}; +} diff --git a/utils/cheat_sheet_src/src/parsers.txt b/utils/cheat_sheet_src/src/parsers.txt new file mode 100644 index 0000000..8fbe6ed --- /dev/null +++ b/utils/cheat_sheet_src/src/parsers.txt @@ -0,0 +1,22 @@ +// packet_in: extern for input packet +extern packet_in { + void extract(out T hdr); + void extract(out T hdr,in bit<32> n); + T lookahead(); + void advance(in bit<32> n); + bit<32> length(); +} + +// parser: begins in special "start" state +state start { + transition parse_ethernet; +} + +// User-defined parser state +state parse_ethernet { + packet.extract(hdr.ethernet); + transition select(hdr.ethernet.type) { + 0x800: parse_ipv4; + default: accept; + } +} \ No newline at end of file diff --git a/utils/cheat_sheet_src/src/tables.txt b/utils/cheat_sheet_src/src/tables.txt new file mode 100644 index 0000000..c7df56e --- /dev/null +++ b/utils/cheat_sheet_src/src/tables.txt @@ -0,0 +1,16 @@ +table ipv4_lpm { + key = { + hdr.ipv4.dstAddr : lpm; + // standard match kinds: + // exact, ternary, lpm + } + // actions that can be invoked + actions = { + ipv4_forward; + drop; + NoAction; + } + // table properties + size = 1024; + default_action = NoAction(); +} \ No newline at end of file diff --git a/utils/cheat_sheet_src/src/v1model_std_metadata.txt b/utils/cheat_sheet_src/src/v1model_std_metadata.txt new file mode 100644 index 0000000..5b10226 --- /dev/null +++ b/utils/cheat_sheet_src/src/v1model_std_metadata.txt @@ -0,0 +1,22 @@ +struct standard_metadata_t { + bit<9> ingress_port; + bit<9> egress_spec; + bit<9> egress_port; + bit<32> clone_spec; + bit<32> instance_type; + bit<1> drop; + bit<16> recirculate_port; + bit<32> packet_length; + bit<32> enq_timestamp; + bit<19> enq_qdepth; + bit<32> deq_timedelta; + bit<19> deq_qdepth; + bit<48> ingress_global_timestamp; + bit<48> egress_global_timestamp; + bit<32> lf_field_list; + bit<16> mcast_grp; + bit<32> resubmit_flag; + bit<16> egress_rid; + bit<1> checksum_error; + bit<32> recirculate_flag; +} \ No newline at end of file