diff --git a/.gitignore b/.gitignore index b5b5524..4f8defe 100644 --- a/.gitignore +++ b/.gitignore @@ -454,4 +454,34 @@ $RECYCLE.BIN/ *.lnk -# End of https://www.gitignore.io/api/latex,linux,macos,python,windows,phpstorm \ No newline at end of file +# End of https://www.gitignore.io/api/latex,linux,macos,python,windows,phpstorm + +#own ignores +# Python byte code +*.pyc + +# Emacs +*~ + +# Compiled JSON +*.json +!*p4app*.json + +*.pcap + +# Build folders +build*/ +log*/ +pcap*/ +*.pickle + +*.db + +*.p4i +*.p4rt + +#latex +*.aux +*.bbl +*.log +*.out \ No newline at end of file diff --git a/examples/bin/install-emacs-mode.sh b/examples/bin/install-emacs-mode.sh deleted file mode 100644 index 77e139d..0000000 --- a/examples/bin/install-emacs-mode.sh +++ /dev/null @@ -1,7 +0,0 @@ -sudo cp p4_16-mode.el /usr/share/emacs/site-lisp/ -sudo mkdir -p /home/edgar/.emacs.d/ -echo "(autoload 'p4_16-mode' \"p4_16-mode.el\" \"P4 Syntax.\" t)" > init.el -echo "(add-to-list 'auto-mode-alist '(\"\\.p4\\'\" . p4_16-mode))" | tee -a init.el -sudo mv init.el /home/edgar/.emacs.d/ -sudo ln -s /usr/share/emacs/site-lisp/p4_16-mode.el /home/edgar/.emacs.d/p4_16-mode.el -sudo chown -R edgar:edgar /home/edgar/.emacs.d/ diff --git a/examples/bin/install.sh b/examples/bin/install.sh deleted file mode 100644 index 4d34004..0000000 --- a/examples/bin/install.sh +++ /dev/null @@ -1,93 +0,0 @@ -#!/bin/bash - - -#Install Dependencies (ubuntu 16.04 is recommended. In ubuntu 14.04 some dependencies have to be installed manually) - -apt-get install -y \ - git \ - mininet \ - autoconf \ - automake \ - libtool \ - curl \ - make \ - g++ \ - unzip \ - libgc-dev \ - bison \ - flex \ - libfl-dev \ - libgmp-dev \ - libboost-dev \ - libboost-iostreams-dev \ - pkg-config \ - python \ - python-scapy \ - python-ipaddr \ - tcpdump \ - cmake - -#create directory p4 (if it does not exist) in home. And cd - -mkdir -p $HOME/p4 -cd $HOME/p4 - -# Bmv2 -git clone https://github.com/p4lang/behavioral-model bmv2 -cd bmv2 -./install_deps.sh -./autogen.sh -./configure -make -sudo make install -sudo ldconfig -cd .. - -#P4C-bmv2 (old compiler, deprecated soon?) -git clone https://github.com/p4lang/p4c-bm.git -cd p4c-bm -sudo pip install -r requirements.txt -sudo python setup.py install -cd .. - -# Protobuf -git clone https://github.com/google/protobuf.git -cd protobuf -git checkout v3.2.0 -./autogen.sh -./configure -make -sudo make install -sudo ldconfig -cd .. - -# libboost 1.57 is required - -wget boost_1_58_0.tar.gz http://sourceforge.net/projects/boost/files/boost/1.58.0/boost_1_58_0.tar.gz/download -tar xzvf boost_1_57_0.tar.gz -cd boost_1_58_0/ - -./bootstrap.sh --prefix=/usr/local -user_configFile=`find $PWD -name user-config.jam` -echo "using mpi ;" >> $user_configFile - -sudo ./b2 --with=all -j 4 install - -sudo sh -c 'echo "/usr/local/lib" >> /etc/ld.so.conf.d/local.conf' -sudo ldconfig - -# P4C -git clone --recursive https://github.com/p4lang/p4c -cd p4c -mkdir build -cd build -#only if cmake < 3.0.2 -#sudo apt-get install software-properties-common -#sudo add-apt-repository ppa:george-edison55/cmake-3.x -#sudo apt-get update -#sudo apt-get install --only-upgrade cmake -cmake .. -make -j4 -sudo make install -cd .. -cd .. diff --git a/examples/bin/update-bmv2.sh b/examples/bin/update-bmv2.sh deleted file mode 100644 index 0e209f1..0000000 --- a/examples/bin/update-bmv2.sh +++ /dev/null @@ -1,53 +0,0 @@ -#! /bin/bash - -#save current path to return later -CURRENT_PATH="$(pwd)" - -#enable multi-queueing -if [[ $* == *--hard-clean* ]] -then - sudo rm -rf $HOME/p4/bmv2 - cd $HOME/p4 - git clone https://github.com/p4lang/behavioral-model bmv2 - cd bmv2 -else - #change directory to the directory where p4-bmv2 is - #assumes that bmv2 is installed here: - cd $HOME/p4/bmv2 - # Clean repo - make clean - - # Pull new changes - git pull - - -#enable multi-queueing -if [[ $* == *--enable-multi-queue* ]] -then - sed -i 's/^\/\/ \#define SSWITCH_PRIORITY_QUEUEING_ON/\#define SSWITCH_PRIORITY_QUEUEING_ON/g' targets/simple_switch/simple_switch.h -elif [[ $* == *--disable-multi-queue* ]] -then - sed -i 's/^\#define SSWITCH_PRIORITY_QUEUEING_ON/\/\/ \#define SSWITCH_PRIORITY_QUEUEING_ON/g' targets/simple_switch/simple_switch.h -fi - -#install dependencies again -#./install_deps.sh - -# Compile and install -./autogen.sh - -if [[ $* == *--no-debug* ]]; then - ./configure --disable-elogger --disable-logging-macros 'CFLAGS=-g -O2' 'CXXFLAGS=-g -O2' -else - - # With debug enabled in binaries: - ./configure 'CXXFLAGS=-O0 -g' - # Without debug enabled: - #./configure -fi - -make -j 20 -#install -sudo make install -sudo ldconfig - diff --git a/examples/bin/update-p4c-bm.sh b/examples/bin/update-p4c-bm.sh deleted file mode 100644 index 1bd71f9..0000000 --- a/examples/bin/update-p4c-bm.sh +++ /dev/null @@ -1,11 +0,0 @@ -#! /bin/bash - -#change directory to the directory where p4-bmv2 is - -#assumes that bmv2 is installed here: -cd $HOME/p4/p4c-bm - -git pull -sudo pip install -r requirements.txt -sudo python setup.py install -cd .. diff --git a/examples/bin/update-p4c.sh b/examples/bin/update-p4c.sh deleted file mode 100644 index 5740f98..0000000 --- a/examples/bin/update-p4c.sh +++ /dev/null @@ -1,35 +0,0 @@ -#! /bin/bash - -#save current path to return later -CURRENT_PATH="$(pwd)" - -cd $HOME/p4/p4c - -# Recommended in p4c's README.md -git submodule update --init --recursive - -# Get updates from master repo -git pull - -if [ -d build ] -then - echo "Deleting build directory" - /bin/rm -fr build -fi - -echo "Building p4c from scratch" -mkdir build -cd build - -# Configure for a debug build -cmake .. -DCMAKE_BUILD_TYPE=DEBUG -make -j 4 -sudo make install - -#if needed -#copy custom v1model.p4 -if [[ $* == *--update-v1model* ]] -then - cd "$CURRENT_PATH" - cp ../docs/includes/v1model.p4 /usr/local/share/p4c/p4include/ -fi \ No newline at end of file diff --git a/examples/docs/JSON_format.md b/examples/docs/JSON_format.md deleted file mode 100644 index 9d86469..0000000 --- a/examples/docs/JSON_format.md +++ /dev/null @@ -1,703 +0,0 @@ -# BMv2 JSON input format - -All bmv2 target switches take as input a JSON file, whose format is essentially -target independent. The format is very simple and several examples can be found -in this repository, including -[here](../targets/simple_router/simple_router.json). - -This documents attempt to describe the expected JSON schema and the constraints -on each attribute. - -## Current bmv2 JSON format version - -The version described in this document is *2.14*. - -The major version number will be increased by the compiler only when -backward-compatibility of the JSON format is broken. After a major version -number increase, consummers of the JSON file may need to be updated or they may -not be able to consume newer JSON files. - -Starting with version 2.0, the version number is included in the JSON file -itself, under the key `__meta__` -> `version`. - -Note that the bmv2 code will perform a version check against the provided input -JSON. - -## General information - -Tentative support for signed fields (with a 2 complement representation) has -been added to bmv2, although they are not supported in P4 1.0 or by the [p4c-bm -compiler](https://github.com/p4lang/p4c-bm). However, signed constants (in -expressions, or as primitive arguments) are always supported. -Arithmetic is done with infinite precision, but when a value is copied into a -field, it is truncated based on the field's bitwidth. - -## Format - -### The type value object - -You will see many places where a JSON object with 2 attributes, `type` and -`value`, is expected (for example, action primitive arguments). This is the -convention we follow: -- if `type` is `field`, `value` is a JSON 2-tuple, where the first item is the -header instance name and the second is the field member name. -- if `type` is `hexstr`, `value` is a bitstring written in hexadecimal (big -endian order); it can be prefixed with a negative sign, for negative values. -- if `type` is `bool`, `value` is either `true` or `false`. -- if `type` is a named P4 type (`header`, `header_stack`, `calculation`, -`register_array`, `meter_array`, `counter_array`, `header_union`, -`header_union_stack`), `value` is a string corresponding to the name of the -designated object. -- if `type` is `string`, `value` is a sequence of characters. -- if `type` is `lookahead` (parser only), `value` is a JSON 2-tuple, where the -first item is the bit offset for the lookahead and the second item is the -bitwidth. -- if `type` is `register`, `value` is a JSON 2-tuple, where the first item is -the register array name and the second is an `expression` used to evaluate the -index. -- if `type` is `stack_field`, `value` is a JSON 2-tuple, where the first item is -the header stack name and the second is the field member name. This is used to -access a field in the last valid header instance in the stack. -- if `type` is `union_stack_field`, `value` is a JSON 3-tuple, where the first item is -the header union stack name, the second is the union member name and the third -is the field member name. This can be used exclusively in the `transition_key` -of a parser to access a field in the last valid union instance in the stack. -- if `type` is `expression`, `value` is a JSON object with 3 attributes: - - `op`: the operation performed (`+`, `-`, `*`, `<<`, `>>`, `==`, `!=`, `>`, - `>=`, `<`, `<=`, `and`, `or`, `not`, `&`, `|`, `^`, `~`, `valid`, - `valid_union`) - - `left`: the left side of the operation, or `null` if unary operation - - `right`: the right side of the operation -- if `type` is `local`, `value` is an integer representing an index inside an -array of local integral values. This `type` can only be used inside of an -expression, i.e. if this JSON object has a parent whose `type` attribute is -`expression`. The meaning of these "local integral values" depend on the context -in which the parent expression is evaluated. In the case of an expression being -evaluated inside of an action function belonging to a match-action table, the -local integral values correspond to the runtime data available for a given table -entry (see the [actions](#actions) section for more details on runtime data). - -For an expression, `left` and `right` will themselves be JSON objects, where the -`value` attribute can be one of `field`, `hexstr`, `header`, `expression`, -`bool`, `register`, `header_stack`, `stack_field`. - -bmv2 also supports these recently-added operations: - - data-to-bool conversion (`op` is `d2b`): unary operation which can be used -to explicitly convert a data value (i.e. a value that can be read from / -written to a field, or a value obtained from runtime action data, or a value -obtained from a JSON `hexstr`) to a boolean value. Note that implicit -conversions are not supported. - - bool-to-data conversion (`op` is `b2d`): unary operation which can be used -to explicitly convert a boolean value to a data value. Note that implicit -conversions are not supported. - - 2-complement modulo (`op` is `two_comp_mod`): given a source data value and -a width data value, produces a third data value which is the signed value of the -source given a 2-complement representation with that width. For example, -`two_comp_mod(257, 8) == 1` and `two_comp_mod(-129, 8) == 127`. - - ternary operator (`op` is `?`): in addition to `left` and `right`, the JSON -object has a fourth attribute, `cond` (condition), which is itself an -expression. For example, in `(hA.f1 == 9) ? 3 : 4`, `cond` would be the JSON -representation of `(hA.f1 == 9)`, `left` would be the JSON representation of `3` -and `right` would be the JSON representation of `4`. - - stack header access (`op` is `dereference_header_stack`): `left` is a -`header_stack` and `right` needs to evaluate to a valid index inside the stack; -the expression produces a `header`. - - last valid index in a stack (`op` is `last_stack_index`): unary operation -which takes a `header_stack` and produces the index of the last valid `header` -in the stack as a data value. - - size of a stack (`op` is `size_stack`): unary operation which takes a -`header_stack` and produces the size of the stack (i.e. number of valid headers -in the stack) as a data value. - - access to the header field at a given offset (`op` is `access_field`): -`left` needs to evaluate to a `header` and `right` is a JSON integer -representing a valid field offset for that header; the expression returns the -header field at the given offset. The interest of this operation is that the -`header` needs not be known at compile time, it can be a stack member resolved -at runtime. - - stack union access (`op` is `dereference_union_stack`): `left` is a -`header_union_stack` and `right` needs to evaluate to a valid index inside the -stack; the expression produces a `header`. - - access to the header union member at a given offset (`op` is -`access_union_header`): `left` needs to evaluate to a `header_union` and `right` -is a JSON integer representing a valid member offset for that union; the -expression returns the header at the given offset. The interest of this -operation is that the `header_union` needs not be known at compile time, it can -be a union stack entry resolved at runtime. - -For field references, some special values are allowed. They are called "hidden -fields". For now, we only support one kind of hidden fields: `
.$valid$`. This field is a 1-bit field which encodes the validity of the -corresponding header. It is a read-only field. It can be used just like any -other field; in particular as part of a match-table key or in a control-flow -condition. In the long run, this field will completely replace the valid match -type and the `valid()` built-in (in expressions), but we are not there yet. - - -The attributes of the root JSON dictionary are: - -### `__meta__` - -It is a JSON object which includes some meta information about the JSON file. It -has the following attributes: -- `version`: a JSON array with exactly 2 integer entries, a major version number -and a minor version number. -- `compiler`: an optional string to help identify the P4 compiler which produced -the JSON. - -### `header_types` - -It is a JSON array of all the header types defined in the P4 program. Each array -item has the following attributes: -- `name`: fully qualified P4 name of the header type -- `id`: a unique integer (unique with respect to other header types) -- `fields`: a JSON array of JSON 2-tuples (field member name, field width in -bits). Note that the JSON 2-tuples can optionally be JSON 3-tuples if you want -to experiment with signed fields support. In this case, the third element of the -tuples is a boolean value, which is `true` iff the field is signed. A signed -field needs to have a bitwidth of at least 2! For variable length fields, the -field width is `"*"`. There can be at most one variable-length field in a header -type. When a variable-length field is present, the header type is required to -have the `length_exp` attribute. -- `length_exp`: this attribute is only present when the header type includes a -variable-length field, in which case this attribute must be an expression -resolving to an integral value, corresponding to the variable-length field's -bitwidth. -- `max_length`: this attribute needs only be present when the header type -includes a variable-length field, in which case this attribute is the maximum -width in bytes for the header. - -### `headers` - -It is a JSON array of all the header instances (including metadata) declared in -the P4 program. Each array item has the following attributes: -- `name` -- `id`: a unique integer (unique with respect to other header instances) -- `header_type`: the `name` of the header type for this header instance -- `metadata`: a boolean value, `true` iff the instance is a metadata instance - -### `header_stacks` - -It is a JSON array of all the header stacks declared in the P4 program. Each -array item has the following attributes: -- `name` -- `id`: a unique integer (unique with respect to other header stacks) -- `header_type`: the `name` of the header type for this stack -- `header_ids`: a JSON array of integers; each integer being the unique `id` of -a header instance included in the stack. These ids have to be in the correct -order: stack[0], stack[1], ... - -### `header_union_types` - -It is a JSON array of all the header union types declared in the P4 -program. Each array item has the following attributes: -- `name` -- `id`: a unique integer (unique with respect to other header union types) -- `headers`: a JSON array of 2-tuples, where the first element is the P4 name of -the corresponding union member, and the second element is the name of the header -type for this element. - -### `header_unions` - -It is a JSON array of all the header unions declared in the P4 program. Each -array item has the following attributes: -- `name` -- `id`: a unique integer (unique with respect to other header unions) -- `union_type`: the name of the corresponding header union type for this union -instance -- `header_ids`: a JSON array of integers, each integer being the unique `id` of -a header instance included in the union. We recommend using the same order as in -the corresponding P4 declaration. - -### `header_union_stacks` - -It is a JSON array of all the header union stacks declared in the P4 -program. Each array item has the following attributes: -- `name` -- `id`: a unique integer (unique with respect to other header union stacks) -- `union_type`: the name of the corresponding header union type for the elements -of this stack. -- `header_union_ids`: a JSON array of integers, each integer being the unique -`id` of a header union instance included in the stack. These ids have to be in -the correct order: union_stack[0], union_stack[1], ... - -### `errors` - -It is a JSON array of all the errors declared in the P4 program (error -declarations were introduced in P4_16 and can be raised in parsers). Each array -item is itself an array with exactly 2 elements: the name of the error as it -appears in the P4 program and an integer value in the range `[0, 2**31 - 1)`. It -is up to the compiler to assign a *unique* integer value to each declared error; -if the error constant is used in the parser (e.g. in a `verify` statement) or in -a control, it is up to the compiler to consistently replace each error with its -assigned value when producing the bmv2 JSON. bmv2 supports the core library -errors, but it is up to the compiler to include them in this JSON array and -assign a value to them (however this is not strictly necessary if these core -error constants are not used anywhere in the program). - -We recommend using 0 for the core library error `NoError`, but this is not -strictly necessary. Note that the value `2**31 - 1` is reserved and cannot be -assigned by the compiler. - -### `enums` - -Its is a JSON array of all the enums declared in the P4 program (enum -declarations were introduced in P4_16). Each array item has the following -attributes: -- `name`: name of the enum, as it appears in the p4 program -- `entries`: a JSON array of all the constants declared inside the enum. Each -array item is itself an array with exactly 2 elements: the name of the enum -constant as it appears in the P4 program and an integer value in the range `[0, -2**31 - 1)`. It is up to the compiler to assign a *unique* integer value (unique -with respect to the other constants in the enum) to each enum constant; if the -enum constant is used in an expression in the P4 program, it is up to the -compiler to consistently replace each reference with its assigned value when -producing the bmv2 JSON. This is very similar to how we handle -[errors](#errors). - -### `parsers` - -It is a JSON array of all the parsers declared in the P4 program. Each array -item has the following attributes: -- `name` -- `id`: a unique integer (unique with respect to other parsers) -- `init_state`: the name of the start state for the parser -- `parse_states`: a JSON array of JSON objects. Each of these objects stores the -information for a given parse state in the program, which is used by the current -parser. The attributes for these objects are: - - `name` - - `id`: a unique integer; note that it has to be unique with respect to *all* - parse states in the JSON file, not just the parse states included in this - parser object - - `parser_ops`: a JSON array of the operations performed in this parse state, - in the correct order. Each parser operation is represented by a JSON object, - whose attributes are: - - `op`: the type of operation, either `extract`, `extract_VL`, `set`, - `verify`, `shift` or `primitive`. - - `parameters`: a JSON array of objects encoding the parameters to the - parser operation. Depending on the type of operation, the constraints are - different. A description of these constraints is included [later in this - section](#parser-operations). - - `transition_key`: a JSON array (in the correct order) of objects which - describe the different fields of the parse state transition key. Each object - has 2 attributes, `type` and `value`, where `type` can be either - `field`, `stack_field` (for a field of the last extracted instance in a - stack), `union_stack_field` (for a field of the last extracted instance in a - union stack) or `lookahead` (see [here](#the-type-value-object)). - - `transitions`: a JSON array of objects encoding each parse state - transition. The different attributes for these objects are: - - `type`: either `default` (for the default transition), `hexstr` (for a - regular hexstring value-based transition) or `parse_vset` (for a parse - value-set). - - `value`: only relevant if the `type` attribute is `hexstr`, in which case - it is the hexstring value for the transition, or `parse_vset`, in which case - it is the name of the corresponding parse value-set. Set to `null` if `type` - is `hexstr`. - - `mask`: only relevant if the `type` attribute is `hexstr` or `parse_vset` - (`null` if `type` is `default`). It can either be a hexstring (to be used as - a mask and ANDed with the key and the value) or `null`. For a parse - value-set, the mask will be ANDed with each value in the set when checking - for a match. - - `next_state`: the name of the next parse state, or `null` if this is the - last state in the parser. - -For values and masks, make sure that you use the correct format. They need to be -the concatenation (in the right order) of all byte padded fields (padded with -`0` bits). For example, if the transition key consists of a 12-bit field and a -2-bit field, each value will need to have 3 bytes (2 for the first field, 1 for -the second one). If the transition value is `0xaba`, `0x3`, the `value` -attribute will be set to `0x0aba03`. - -#### parser operations - -In the `parser_ops` array, the format of the `parameters` array depends on the -`op` value: - - `extract`: only takes one parameter, of type `regular` (extraction to a - regular header instance), `stack` (extraction to the end of a header stack) or - `union_stack` (extraction to the end of a header union stack). If `type` is - `regular`, `value` is the name of the header instance to extract. If `type` is - `stack`, `value` is the name of the header stack. Finally if `type` is - `union_stack`, then `value` is a 2-tuple with the name of the header union - stack as the first element and the name of the appropriate union member as the - second element. - - `extract_VL`: introduced for P4_16, where the expression to dynamically - compute the length of a variable-length field is an argument to the extract - built-in rather than a property of the header. For this operation, we require - 2 parameters, the first one of type `regular` and the second one of type - `expression` (to compute the length in bits of the variable-length field in - the header). - - `set`: takes exactly 2 parameters; the first one needs to be of type `field` - with the appropriate value. The second one can be of type `field`, `hexstr`, - `lookahead` or `expression`, with the appropriate value (see - [here](#the-type-value-object)). - - `verify`: we expect an array with exactly 2 elements; the first should be a - boolean expression while the second should be an expression resolving to a - valid integral value for an error constant (see [here](#errors)). - - `shift`: we expect a single parameter, the number of bytes to shift (shifted - packet data will be discarded). - - `primitive`: introduced for P4_16, where extern methods can be called from - parser states. It only takes one parameter, which is itself a JSON object with - the following attributes: - - `op`: the primitive name. This primitive has to be supported by the - target. - - `parameters`: a JSON array of the arguments passed to the primitive (has - to match the target primitive definition). Each argument is represented by a - [type-value](#the-type-value-object) JSON object. This is consistent with how - control-flow actions are described in the JSON, so you can refer to the - [actions](#actions) section for more details. - -We provide an example of parser operations for a parser state: -```json -"parser_ops": [ - { - "op": "extract", - "parameters": [ - {"type": "regular", "value": "ethernet"} - ] - }, - { - "op": "primitive", - "parameters": [ - { - "op": "assign_header", - "parameters": [ - {"type": "header", "value": "ethernet_copy"}, - {"type": "header", "value": "ethernet"}, - ] - } - ] - } -] -``` - -### `parse_vsets` - -It is a JSON array of all the parse value-sets declared in the P4 program. Each -array item has the following attributes: -- `name` -- `id`: a unique integer (unique with respect to other parse value-sets) -- `compressed_bitwidth`: the bitwidth of the values which can be added to the -set. Note that this bitwidth does not include any padding. - -### `deparsers` - -It is a JSON array of all the deparsers declared in the P4 program (or inferred -from P4 parsers). Each array item has the following attributes: -- `name` -- `id`: a unique integer (unique with respect to other deparsers) -- `order`: a JSON array of sorted header instance names. When the target switch -invokes a deparser, the headers will be serialized in this order, and non-valid -headers will be skipped. - -For stacks and unions, all the header instances need to be listed in the -appropriate order. - -### `meter_arrays` - -It is a JSON array of all the meter arrays declared in the P4 program. Each -array item has the following attributes: -- `name` -- `id`: a unique integer (unique with respect to other meter arrays) -- `type`: either `bytes` or `packets` -- `rate_count`: the number of rates for the meters. By default P4 uses 2-rate -3-color meters -- `size`: the number of meter instances in the array -- `is_direct`: a boolean indicating whether this is a direct meter array -- `binding`: if the meter array is direct, the name of the table it is attached -to -- `result_target`: a 2-tuple representing the field where the meter result -(color) will be stored; only taken into account if `is_direct` is `true`. - -### `counter_arrays` - -It is a JSON array of all the counter arrays declared in the P4 program. Each -array item has the following attributes: -- `name` -- `id`: a unique integer (unique with respect to other counter arrays) -- `size`: the number of counter instances in the array -- `is_direct`: a boolean indicating whether this is a direct counter array -- `binding`: if the counter array is direct, the name of the table it is -attached to - -Unlike for meter arrays, there is no `type` attribute because bmv2 counters -always count both bytes and packets. - -### `register_arrays` - -It is a JSON array of all the register arrays declared in the P4 program. Each -array item has the following attributes: -- `name` -- `id`: a unique integer (unique with respect to other register arrays) -- `size`: the number of register instances in the array -- `bitwidth`: the width in bits of each register cell - -### `actions` - -It is a JSON array of all the actions declared in the P4 program. Each array -item has the following attributes: -- `name` -- `id`: a unique integer (unique with respect to other actions) -- `runtime_data`: a JSON array of objects, each one representing a named -parameter of the action. Each object has exactly 2 attributes: - - `name`: the P4 name of the parameter - - `bitwidth`: the integral width, in bits, of the parameter -- `primitives`: a JSON array of objects, each one representing a primitive -call, with the following attributes: - - `op`: the primitive name. This primitive has to be supported by the target. - - `parameters`: a JSON array of the arguments passed to the primitive (has to - match the target primitive definition). Each argument is represented by a JSON - object with the following attributes: - - `type`: one of `hexstr`, `runtime_data`, `header`, `field`, `calculation`, - `meter_array`, `counter_array`, `register_array`, `header_stack`, - `expression`, `extern`, `string`, 'stack_field' - - `value`: the appropriate parameter value. If `type` is `runtime_data`, - this is an integer representing an index into the `runtime_data` (attribute - of action) array. If `type` is `extern`, this is the name of the extern - instance. See [here](#the-type-value-object) for other types. - -*Important note about extern instance methods*: even though in P4 these are -invoked using object-oriented style, bmv2 treats them as regular primitives for -which the first parameter is the extern instance. For example, if the P4 call is -`extern1.methodA(x, y)`, where `extern1` is an extern instance of type -`my_extern_type`, the bmv2 compiler needs to translate this into a call to -primitive `_my_extern_type_methodA`, with the first parameter being `{"type": -"extern", "value": "extern1"}` and the second parameter being the appropriate -representation for `x` and `y`. - -bmv2 supports the following core primitives: -- `assign`, `assign_VL` (for variable-length fields), `assign_header` and -`assign_union`. -- `push` and `pop` for stack (header stack or header union stack) manipulation. -- `_jump`: takes one parameter which must resolve to an integral value -`offset`. When it is executed, we jump to the primitive call at index `offset` -in the enclosing action. -- `_jump_if_zero`: implements a conditional jump and takes two parameters which -must both resolve to integral values, which we call respectively `cond` and -`offset`. If `cond` is 0, the primitive behaves exactly like `_jump` and we jump -to the primitive call at index `offset`; otherwise the primitive is a no-op. - -Support for additional primitives depends on the architecture being used. - -### `pipelines` - -It is a JSON array of all the top control flows (ingress, egress) in the P4 -program. Each array item has the following attributes: -- `name` -- `id`: a unique integer (unique with respect to other pipelines) -- `init_table`: the name of the first table of the pipeline -- `action_profiles`: a JSON array of JSON objects. Each of these objects stores -the information for a given P4 action profile, which is used by the current -pipeline. The attributes for these objects are: - - `name` - - `id`: a unique integer; note that it has to be unique with respect to *all* - action profiles in the JSON file, not just the action profiles included in - this pipeline object - - `max_size`: an integer representing the size (number of entries) of the - action profile - - `selector`: only present if the action profile supports dynamic group member - selection. It needs to be a JSON object with these attributes: - - `algo`: the hash algorithm used for group member selection (has to be - supported by target switch) - - `input`: a JSON array of objects with the following attributes: - - `type`: has to be `field` - - `value`: the field reference -- `tables`: a JSON array of JSON objects. Each of these objects stores the -information for a given P4 table, which is used by the current pipeline. The -attributes for these objects are: - - `name` - - `id`: a unique integer; note that it has to be unique with respect to *all* - tables in the JSON file, not just the tables included in this pipeline object - - `match_type`: one of `exact`, `lpm`, `ternary` or `range` - - `type`: the implementation for the table, one of `simple`, `indirect` - (action profiles), `indirect_ws` (action profiles with dynamic selector) - - `action_profile`: if the table is indirect, name of the action profile to - use with this table. If the table type is `indirect_ws`, then the referenced - action profile needs to have a selector attribute. - - `max_size`: an integer representing the size (number of entries) of the - table - - `with_counters`: a boolean, `true` iff the match table has direct counters - - `support_timeout`: a boolean, `true` iff the match table supports ageing - - `key`: the lookup key format, represented by a JSON array. Each member of - the array is a JSON object with the following attributes: - - `match_type`: one of `valid`, `exact`, `lpm`, `ternary`, `range` - - `target`: the field reference as a 2-tuple (or header as a string if - `match_type` if `valid`) - - `mask`: the static mask to be applied to the field, or null. Just like for - the parser transition key, make sure that this mask is byte-padded and has - the same width (in bytes) as the corresponding field (1 byte if `match_type` - is `valid`). - - `actions`: the list of actions (order does not matter) supported by this - table - - `next_tables`: maps each action to a next table name. Alternatively, maps - special string `__HIT__` and `__MISS__` to a next table name. - - `direct_meters`: the name of the associated direct meter array, or null if - the match table has no associated meter array - - `default_entry`: an optional JSON item which can force the default entry for - the table to be set when loading the JSON, without intervention from the - control plane. It has the following attributes: - - `action_id`: the id of the default action - - `action_const`: an optional boolean value which is `true` iff the control - plane is not allowed to change the default action function. Default value is - `false`. - - `action_data`: an optional JSON array where each entry is the hexstring - value for an action argument. The size of the array needs to match the - number of parameters expected by the action function with id `action_id`. - - `action_entry_const`: an optional boolean value which is `true` iff the - control plane is not allowed to modify the action entry (action function + - action data). Default value is `false`. This attribute is ignored if the - `action_data` attribute it missing. - - `entries`: enables you to optionally specify match-action entries for this - table. Specifying entries in the JSON makes the table immutable, which means - the added entries cannot be modified / deleted and that new entries cannot be - added. This doesn't impact the default entry though (see the `default_entry` - attribute). `entries` is a JSON array where each element follows the - [match-action entry format](#match-action-entry-format) described below. -- `conditionals`: a JSON array of JSON objects. Each of these objects stores the -information for a given P4 condition, which is used by the current pipeline. The -attributes for these objects are: - - `name` - - `id`: a unique integer; note that it has to be unique with respect to *all* - conditions in the JSON file, not just the conditions included in this pipeline - object - - `expression`: the expression for the condition. See - [here](#the-type-value-object) for more information on expressions format. - - `true_next`: the name of the next control flow to execute if the condition - evaluates to true (can be a table, another conditional or an action call), or - null if this is the end of the pipeline - - `false_next`: the name of the next control flow to execute if the condition - evaluates to false, or null if this is the end of the pipeline -- `action_calls`: a JSON array of JSON objects. It is used for direct action -calls from a control flow which are not wrapped into a table. The attributes for -these objects are: - - `name` - - `id`: a unique integer; note that it has to be unique with respect to *all* - action calls in the JSON file, not just the ones included in this pipeline - object - - `action_id`: the id of the action to call; note that the corresponding - action must not expect any parameter - - `next_node`: the name of the next control flow node to execute (can be a - table, a conditional or another action call like this one), or null if this is - the last node in the pipeline - -The `match_type` for the table needs to follow the following rules: -- If one match field is `range`, the table `match_type` has to be `range` -- If one match field is `ternary`, the table `match_type` has to be `ternary` -- If one match field is `lpm`, the table `match_type` is either `ternary` or -`lpm` -Note that it is not correct to have more than one `lpm` match field in the same -table. - -#### match-action entry format - -We describe the format of the match-action entries contained in the `entries` -JSON array (see table JSON format above). Each entry is a JSON object with the -following attributes: -- `match_key`: a JSON array of objects with the following attributes: - - `match_type`: one of `valid`, `exact`, `lpm`, `ternary`, `range` - - the other attributes depend on the `match_type`: - - for `valid`: we need a `key` attribute which has to be a boolean - - for `exact`: we need a `key` attribute which has to be a hexstring - - for `lpm`: we need a `key` attribute which has to be a hexstring and a - `prefix_length` attribute which has to be an integer - - for `ternary`: we need a `key` and a `mask` attributes which both have to - be hexstrings - - for `range`: we need a `start` and a `end` attribute which both have to be - hexstrings -- `action_entry`: a JSON object with the following attributes: - - `action_id`: the id of the default action - - `action_data`: a JSON array where each entry is the hexstring value for an - action argument. The size of the array needs to match the number of parameters - expected by the action function with id `action_id`. -- `priority`: an integer which indicates the priority for the entry; it is -ignored if the match type of the table is not `ternary` or `range`. In bmv2 -having a high priority translates into a low numerical value. - -Note that the `match_key` and the `action_entry` need to be formatted -correctly. In particular: -- the number of match fields in the match key needs to match the table -description -- the match types of the match fields in the match key need to match the table -description -- the hexstrings need to have the correct byte-width -- duplicate entries (as determined by the match keys) will trigger an error - -### `calculations` - -It is a JSON array of all the named calculations in the P4 program. In -particular, they are used for checksums. Each array item has the following -attributes: -- `name` -- `id`: a unique integer (unique with respect to other calculations) -- `algo`: the hash algorithm used (has to be supported by target switch) -- `input`: a JSON array of objects with the following attributes: - - `type`: one of `field`, `hexstr`, `header`, `payload` - - `value`: the appropriate value or reference (see - [here](#the-type-value-object)). For `hexstr`, we require an extra attribute - (in addition to `type` and `value`), `bitwidth`, whose value must be a - positive integer equal to the desired bitwidth for the constant. Note that - we require this attribute because the bitwidth cannot be inferred from the - hexadecimal string directly, as the desired bitwidth may not be a multiple - of a byte. - -If `type` is `payload`, all the headers present after the last included header -(or after the enclosing header of the last included field) will be included in -the input, as well as the packet payload. This is necessary for TCP checksum -computation. - -If a header is not valid when the calculation is evaluated, it will be skipped. - -### `checksums` - -It is a JSON array of all the checksums in the P4 program. Each array item has -the following attributes: -- `name` -- `id`: a unique integer (unique with respect to other checksums) -- `target`: the field where the checksum result is written -- `type`: always set to `generic` -- `calculation`: the name of the calculation to use to compute the checksum -- `update`: an optional boolean value, which defaults to `true`; indicates -whether the checksum needs to be updated in deparsers. -- `verify`: an optional boolean value, which defaults to `true`; indicates -whether the checksum needs to be verified in parsers. -- `if_cond`: null if the checksum needs to be verified and / or updated -unconditionally, otherwise a boolean expression, which will determine whether or -not the checksum gets verified and / or updated. See -[here](#the-type-value-object) for more information on expressions format. - -### `learn_lists` - -Not documented yet, use empty JSON array. - -### `extern_instances` - -It is a JSON array of all the extern instances in the P4 program. Each array -item has the following attributes: -- `name` -- `id`: a unique integer (unique with respect to other extern instances) -- `type`: the name of the extern type, the target switch needs to support this -type -- `attribute_values`: a JSON array with the initial values for the attributes of -this extern instance. Each array item has the following attributes: - - `name`: the name of the attribute - - `type`: the type of the attribute, only `hexstr` (integral values), `string` - (for character sequences) and `expression` are supported for now - - `value`: the initial value for the attribute - -### `field_aliases` - -bmv2 target architectures usually require a set of metadata fields to be defined -in the JSON input. For example, simple_switch requires the following fields: -`standard_metadata.ingress_port`, `standard_metadata.packet_length`, -`standard_metadata.instance_type`, `standard_metadata.egress_spec`, -`standard_metadata.egress_port` and `standard_metadata.clone_spec`. These fields -happen to be the standard metadata fields described in the P4_14 -specification. In some cases you may want to use different names for these -fields in a P4 program, which you can accomplish by using field aliases. A field -alias maps the name expected by bmv2 to the name used in the P4 / JSON. - -The `field_aliases` attribute is a JSON array of 2-tuples, with the following -elements: -- a string corresponding to the name expected by the bmv2 target -(e.g. `"standard_metadata.egress_port"`) -- a 2-tuple where the first item is the actual header instance name and the -second is the actual field member name, as they appear in the P4 / JSON input -(e.g. `["my_metadata", "my_egress_port"]`) diff --git a/examples/docs/advanced_primitives.md b/examples/docs/advanced_primitives.md deleted file mode 100644 index f8aa9e5..0000000 --- a/examples/docs/advanced_primitives.md +++ /dev/null @@ -1,16 +0,0 @@ - -* **Generate Digest:** Generate a packet digest and send it to the receiver. - -* **Resubmit:** Resubmit the original packet to the parser with metadata. It can be applied only at the ingress. - -* **Recirculate:** Resubmit the packet after all egress modifications. It can be applied at egress only. - -* **Clone:** Generate a packet digest and send it to the receiver. - - + ingress_to_ingress: Send a copy of the original packet to the parser. Alias: clone_i2i - + egress_to_ingress: Send a copy of the egress packet to the parser. Alias: clone_e2i - + ingress_to_egress: Send a copy of the original packet to the Buffer Mechanism. Alias: clone_i2e - + egress_to_egress: Send a copy of the egress packet to the Buffer Mechanism. Alias: clone_e2e. - - - diff --git a/examples/docs/cli_commands.md b/examples/docs/cli_commands.md deleted file mode 100644 index 581b612..0000000 --- a/examples/docs/cli_commands.md +++ /dev/null @@ -1,85 +0,0 @@ - -# CLI commands -`~/p4/bmv2/targets/simple_switch/sswitch_CLI` - -Through this CLI, methods provided by the `SimpleSwitchAPI` and the `RuntimeAPI` can be accessed. - -## SimpleSwitchAPI -`~/p4/bmv2/targets/simple_switch/sswitch_CLI.py` -- Set depth of one / all egress queue(s): `set_queue_depth []` -- Set rate of one / all egress queue(s): `set_queue_rate []` -- Add mirroring mapping: `mirroring_add ` -- Delete mirroring mapping: `mirroring_delete ` -- Get time elapsed (in microseconds) since the switch started: `get_time_elapsed` -- Get time elapsed (in microseconds) since the switch clock's epoch: `get_time_since_epoch` - - -## RuntimeAPI -`~/p4/bmv2/tools/runtime_CLI.py` - -- Run a shell command: `shell` -- List tables defined in the P4 program: `show_tables` -- List actions defined in the P4 program: `show_actions` -- List one table's actions as per the P4 program: `table_show_actions ` -- Show info about a table: `table_info ` -- Set default action for a match table: `table_set_default ` -- Return the number of entries in a match table (direct or indirect): `table_num_entries
` -- Add entry to a match table: `table_add
=> [priority]` -- Set a timeout in ms for a given entry; the table has to support timeouts: `table_set_timeout ` -- Add entry to a match table: `table_modify
[action parameters]` -- Delete entry from a match table: `table_delete
` -- Add a member to an action profile: `act_prof_create_member [action parameters]` -- Add a member to an indirect match table: `table_indirect_create_member
[action parameters]` -- Delete a member in an action profile: `act_prof_delete_member ` -- Delete a member in an indirect match table: `table_indirect_delete_member
` -- Modify member in an action profile: `act_prof_modify_member [action parameters]` -- Modify member in an indirect match table: `table_indirect_modify_member
[action parameters]` -- Add entry to an indirect match table: `table_indirect_add
=> [priority]` -- Add entry to an indirect match table: `table_indirect_add
=> [priority]` -- Delete entry from an indirect match table: `table_indirect_delete
` -- Set default member for indirect match table: `table_indirect_set_default
` -- Set default group for indirect match table: `table_indirect_set_default
` -- Add a group to an action pofile: `act_prof_create_group ` -- Add a group to an indirect match table: `table_indirect_create_group
` -- Delete a group from an action profile: `act_prof_delete_group ` -- Delete a group: `table_indirect_delete_group
` -- Add member to group in an action profile: `act_prof_add_member_to_group ` -- Add member to group: `table_indirect_add_member_to_group
` -- Remove member from group in action profile: `act_prof_remove_member_from_group ` -- Remove member from group: `table_indirect_remove_member_from_group
` -- Create multicast group: `mc_mgrp_create ` -- Destroy multicast group: `mc_mgrp_destroy ` -- Create multicast node: `mc_node_create [ | ]` -- Update multicast node: `mc_node_update [ | ]` -- Associate node to multicast group: `mc_node_associate ` -- Dissociate node from multicast group: `mc_node_associate ` -- Destroy multicast node: `mc_node_destroy ` -- Set lag membership of port list: `mc_set_lag_membership ` -- Dump entries in multicast engine: `mc_dump` -- Load new json config: `load_new_config_file ` -- Swap the 2 existing configs, need to have called load_new_config_file before: `swap_configs` -- Configure rates for an entire meter array: `meter_array_set_rates : : ...` -- Configure rates for a meter: `meter_set_rates : : ...` -- Retrieve rates for a meter: `meter_get_rates ` -- Read counter value: `counter_read ` -- Reset counter: `counter_reset ` -- Read register value: `register_read ` -- Write register value: `register_write ` -- Reset all the cells in the register array to 0: `register_reset ` -- Display some information about a table entry: `table_dump_entry
` -- Display some information about a member: `act_prof_dump_member ` -- Display some information about a member: `table_dump_member
` -- Display some information about a group: `table_dump_group ` -- Display some information about a group: `table_dump_group
` -- Display entries in an action profile: `act_prof_dump ` -- Display entries in a match-table: `table_dump
` -- Display some information about a table entry: `table_dump_entry_from_key
[priority]` -- Add a port to the switch (behavior depends on device manager used): `port_add [pcap_path]` -- Removes a port from the switch (behavior depends on device manager used): `port_remove ` -- Shows the ports connected to the switch: `show_ports` -- Show some basic info about the switch: `switch_info` -- Reset all state in the switch (table entries, registers, ...), but P4 config is preserved: `reset_state` -- Retrieves the JSON config currently used by the switch and dumps it to user-specified file: `write_config_to_file ` -- Serialize the switch state and dumps it to user-specified file: `serialize_state ` -- Change the parameters for a custom crc16 hash: `set_crc16_parameters ` -- Change the parameters for a custom crc32 hash: `set_crc32_parameters ` \ No newline at end of file diff --git a/examples/docs/includes/core.p4 b/examples/docs/includes/core.p4 deleted file mode 100644 index b52f961..0000000 --- a/examples/docs/includes/core.p4 +++ /dev/null @@ -1,82 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -/* This is the P4-16 core library, which declares some built-in P4 constructs using P4 */ - -#ifndef _CORE_P4_ -#define _CORE_P4_ - -/// Standard error codes. New error codes can be declared by users. -error { - NoError, /// No error. - PacketTooShort, /// Not enough bits in packet for 'extract'. - NoMatch, /// 'select' expression has no matches. - StackOutOfBounds, /// Reference to invalid element of a header stack. - HeaderTooShort, /// Extracting too many bits into a varbit field. - ParserTimeout /// Parser execution time limit exceeded. -} - -extern packet_in { - /// Read a header from the packet into a fixed-sized header @hdr and advance the cursor. - /// May trigger error PacketTooShort or StackOutOfBounds. - /// @T must be a fixed-size header type - void extract(out T hdr); - /// Read bits from the packet into a variable-sized header @variableSizeHeader - /// and advance the cursor. - /// @T must be a header containing exactly 1 varbit field. - /// May trigger errors PacketTooShort, StackOutOfBounds, or HeaderTooShort. - void extract(out T variableSizeHeader, - in bit<32> variableFieldSizeInBits); - /// Read bits from the packet without advancing the cursor. - /// @returns: the bits read from the packet. - /// T may be an arbitrary fixed-size type. - T lookahead(); - /// Advance the packet cursor by the specified number of bits. - void advance(in bit<32> sizeInBits); - /// @return packet length in bytes. This method may be unavailable on - /// some target architectures. - bit<32> length(); -} - -extern packet_out { - /// Write @hdr into the output packet, advancing cursor. - /// @T can be a header type, a header stack, a header_union, or a struct - /// containing fields with such types. - void emit(in T hdr); -} - -// TODO: remove from this file, convert to built-in -/// Check a predicate @check in the parser; if the predicate is true do nothing, -/// otherwise set the parser error to @toSignal, and transition to the `reject` state. -extern void verify(in bool check, in error toSignal); - -/// Built-in action that does nothing. -@name("NoAction") -action NoAction() {} - -/// Standard match kinds for table key fields. -/// Some architectures may not support all these match kinds. -/// Architectures can declare additional match kinds. -match_kind { - /// Match bits exactly. - exact, - /// Ternary match, using a mask. - ternary, - /// Longest-prefix match. - lpm -} - -#endif /* _CORE_P4_ */ diff --git a/examples/docs/includes/debug.p4 b/examples/docs/includes/debug.p4 deleted file mode 100644 index 5fccdb9..0000000 --- a/examples/docs/includes/debug.p4 +++ /dev/null @@ -1,86 +0,0 @@ -// Credits to Andy Fingerhut -// https://github.com/jafingerhut/p4-guide/blob/master/checksum/debug-utils.p4 - - -// Because open source P4 tools do not support using a value of type -// `error` as a field in a table's search key as of 2018-Sep-21, work -// around that limitation by converting parser_error to an unsigned -// integer. We will use _that_ converted value for debug table -// purposes. - -// It is easy to add more possible `error` type values to this -// conversion if you wish, but there is no way in P4_16 to -// automatically iterate over all additional possible values that a -// user program might have defined for type `error`. - -control convert_error_to_bitvector(out bit<8> error_as_int, - in error e) -{ - apply { - if (e == error.NoError) { - error_as_int = 0; - } else if (e == error.PacketTooShort) { - error_as_int = 1; - } else if (e == error.NoMatch) { - error_as_int = 2; - } else if (e == error.StackOutOfBounds) { - error_as_int = 3; - } else if (e == error.HeaderTooShort) { - error_as_int = 4; - } else if (e == error.ParserTimeout) { - error_as_int = 5; - } else { - // Unknown value - error_as_int = 0xff; - } - } -} - -control debug_std_meta(in standard_metadata_t standard_metadata) -{ - bit<8> parser_error_as_int; - convert_error_to_bitvector() convert_err; - table dbg_table { - key = { - // This is a complete list of fields inside of the struct - // standard_metadata_t as of the 2018-Sep-01 version of - // p4c in the file p4c/p4include/v1model.p4. - - // parser_error is commented out because the p4c back end - // for bmv2 as of that date gives an error if you include - // a field of type 'error' in a table key. - - // drop and recirculate_port are commented out because - // they are not used by BMv2 simple_switch, and we may - // want to delete them from v1model.p4 in the future. - standard_metadata.ingress_port : exact; - standard_metadata.egress_spec : exact; - standard_metadata.egress_port : exact; - standard_metadata.clone_spec : exact; - standard_metadata.instance_type : exact; - //standard_metadata.drop : exact; - //standard_metadata.recirculate_port : exact; - standard_metadata.packet_length : exact; - standard_metadata.enq_timestamp : exact; - standard_metadata.enq_qdepth : exact; - standard_metadata.deq_timedelta : exact; - standard_metadata.deq_qdepth : exact; - standard_metadata.ingress_global_timestamp : exact; - standard_metadata.egress_global_timestamp : exact; - standard_metadata.lf_field_list : exact; - standard_metadata.mcast_grp : exact; - standard_metadata.resubmit_flag : exact; - standard_metadata.egress_rid : exact; - standard_metadata.checksum_error : exact; - standard_metadata.recirculate_flag : exact; - //standard_metadata.parser_error : exact; - parser_error_as_int : exact; - } - actions = { NoAction; } - const default_action = NoAction(); - } - apply { - convert_err.apply(parser_error_as_int, standard_metadata.parser_error); - dbg_table.apply(); - } -} \ No newline at end of file diff --git a/examples/docs/includes/p4d2model.p4 b/examples/docs/includes/p4d2model.p4 deleted file mode 100644 index d306514..0000000 --- a/examples/docs/includes/p4d2model.p4 +++ /dev/null @@ -1,224 +0,0 @@ -/* -*- P4_16 -*- */ - -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -/* P4-16 declaration of the P4-D2 (P4 Developer's Day) switch model */ - -#include - -/*************************************************************************** - *************** C O M M O N P O R T A B L E T Y P E S ***************** - *************** A N D C O N S T A N T S ***************** - ***************************************************************************/ -typedef bit<9> portid_t; /* Port ID -- ingress or egress port */ -typedef bit<16> mgid_t; /* Multicast Group ID */ -typedef bit<16> cloneid_t; /* Clone ID */ -typedef bit<16> rid_t; /* Replication ID */ -typedef bit<5> qid_t; /* Queue ID */ -typedef bit<48> timestamp_t; -typedef bit<16> queue_depth_t; -typedef bit<16> packet_length_t; -typedef bit<16> queue_id_t; - -/* Additional, architecture-specific match kinds */ -match_kind { - range -} - -/**************************************************************************** - ********** S T A N D A R D I N T R I N S I C M E T A D A T A ************ - ****************************************************************************/ -struct standard_metadata_t { - portid_t ingress_port; /* The packet the port ingressed in */ - portid_t egress_port; /* Used of mcast_group != 0 */ - mgid_t mcast_group; /* Non-zero value specifies multicast group */ - bit<1> resubmit_flag; /* The resubmit() indicator */ - bit<1> drop_flag; /* Packet (but not clone) is dropped */ - cloneid_t clone_id; /* Non-zero value identifies clone_i2e dest */ - qid_t egress_queue; /* Requested Queue to hold the packet in */ -} - -/**************************************************************************** - ** C H E C K S U M V E R I F I E R I N T R I N S I C M E T A D A T A ** - ****************************************************************************/ - -/**************************************************************************** - ********** I N G R E S S I N T R I N S I C M E T A D A T A ************* - ****************************************************************************/ -struct ingress_input_t { - timestamp_t ingress_timestamp; /* Ingress timestamp */ -} - -/**************************************************************************** - ********** E G R E S S I N T R I N S I C M E T A D A T A ************* - ****************************************************************************/ -struct egress_input_t { - rid_t egress_rid; /* Multicast RID (0 for unicast) */ - packet_length_t packet_length; /* Packet length in bytes */ - - timestamp_t enq_timestamp; /* The time the packet was enqueued */ - timestamp_t deq_timedelta; /* The time spent in the queue */ - queue_depth_t enq_qdepth; /* Q depth when packet was enqueued */ - queue_depth_t deq_qdepth; /* Q depth when packet was dequeued */ -} - -/**************************************************************************** - ** C H E C K S U M U P D A T E R I N T R I N S I C M E T A D A T A ** - ****************************************************************************/ - -/*************************************************************************** - ********* D E P A R S E R I N T R I N S I C M E T A D A T A ************ - ***************************************************************************/ - -/*************************************************************************** - ********** S T A T E F U L E X T E R N O B J E C T S ***************** - ***************************************************************************/ - -/************************ Header Checksum Units ****************************/ -extern Checksum16 { - Checksum16(); - bit<16> get(in D data); -} - -/******************************* Counters **********************************/ -enum counter_type_t { - packets, - bytes, - packets_and_bytes -} - -extern counter { - counter(T instance_count, counter_type_t type); - void count(in T index); -} - -/* Must be referecened in the table declaration via counters= attribute */ -extern direct_counter { - direct_counter(counter_type_t type); - void count(); -} - -/******************************** Meters ***********************************/ -enum meter_type_t { - packets, - bytes -} - -typedef bit<2> meter_color_t; -const meter_color_t METER_COLOR_GREEN = 0; -const meter_color_t METER_COLOR_YELLOW = 1; -const meter_color_t METER_COLOR_RED = 2; - -extern meter { - meter(T instance_count, meter_type_t type); - meter_color_t execute_meter(in T index); -} - -/* Must be referecened in the table declaration via meters= attribute */ -extern direct_meter { - direct_meter(meter_type_t type); - meter_color_t execute_meter(); -} - -/****************************** Registers **********************************/ -extern register { - register(I instance_count); - T read(in I index); - void write(in I index, in T value); -} - -/********************** Random Number Generators ***************************/ -extern random { - random(T lo, T hi); - T get(); -} - -/******************** Hash (CRC) Calculation Units *************************/ -enum hash_algorithm_t { - identity, - crc16, - crc32, - random, - custom -} - -extern hash { - hash(hash_algorithm_t algo); - T compute(in D data, in T base, in T max); -} - -/************************* Digest Generation ******************************/ -typedef bit<32> digest_receiver_t; -extern digest { - digest(digest_receiver_t receiver); - void generate(in T data); -} - -/*************************************************************************** - ************** C O N V E N I E N C E F U N C T I O N S ******************** - ***************************************************************************/ - -/* - * Note: These actions assume that the parameters in the user-instantiated - * controls are named the same way as in the architecture definition - */ -#define mark_for_drop() { standard_metadata.drop_bit = 1; } - -#define drop() { mark_for_drop(standard_metadata); exit; } - -#define resubmit() { standard_metadata.resubmit_flag = 1; } - -#define clone_to_egress(clone_id) { standard_metadata.clone_id = clone_id; } - -/*************************************************************************** - ***************** P A C K A G E C O M P O N E N T S ******************** - ***************************************************************************/ - -parser Parser(packet_in b, - out H parsedHdr, - inout M meta, - inout standard_metadata_t standard_meta); - -control VerifyChecksum(in H hdr, - inout M meta); - -@pipeline -control Ingress(inout H hdr, - inout M meta, - in error parser_error, - in ingress_input_t input_meta, - inout standard_metadata_t output_meta); - -@pipeline -control Egress(inout H hdr, - inout M meta, - in egress_input_t input_meta, - inout standard_metadata_t output_meta); - -control ComputeChecksum(inout H hdr, - inout M meta); - -@deparser -control Deparser(packet_out b, in H hdr); - -package P4D2Switch(Parser user_parser, - VerifyChecksum user_checksum_verification, - Ingress user_ingress, - Egress user_egress, - ComputeChecksum user_checksum_compute, - Deparser user_deparser - ); diff --git a/examples/docs/includes/psa.p4 b/examples/docs/includes/psa.p4 deleted file mode 100644 index c668515..0000000 --- a/examples/docs/includes/psa.p4 +++ /dev/null @@ -1,579 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef _PORTABLE_SWITCH_ARCHITECTURE_P4_ -#define _PORTABLE_SWITCH_ARCHITECTURE_P4_ - -/** - * P4-16 declaration of the Portable Switch Architecture - */ - -/** - * These types need to be defined before including the architecture file - * and the macro protecting them should be defined. - */ -#ifndef PSA_CORE_TYPES -typedef bit PortId_t; -typedef bit MulticastGroup_t; -typedef bit PacketLength_t; -typedef bit EgressInstance_t; -typedef bit InstanceType_t; -typedef bit ParserStatus_t; -typedef bit ParserErrorLocation_t; -typedef bit entry_key; /// for DirectMeters -const InstanceType_t INSTANCE_NORMAL = unspecified; -const PortId_t PORT_CPU = unspecified; -#endif - -#include "core.p4" - -/* --------------------------------------------------------------------- * -/** - * PSA supported metadata types - */ -struct psa_parser_input_metadata_t { - PortId_t ingress_port; - InstanceType_t instance_type; -} - -struct psa_ingress_input_metadata_t { - PortId_t ingress_port; - InstanceType_t instance_type; /// Clone or Normal - /// set by the runtime in the parser, these are not under programmer control - ParserStatus_t parser_status; - ParserErrorLocation_t parser_error_location; -} - -struct psa_ingress_output_metadata_t { - PortId_t egress_port; -} - -struct psa_egress_input_metadata_t { - PortId_t egress_port; - InstanceType_t instance_type; /// Clone or Normal - EgressInstance_t instance; /// instance coming from PRE -} - -/* --------------------------------------------------------------------- */ -/** - * Additional supported match_kind types - */ -match_kind { - range, /// Used to represent min..max intervals - selector /// Used for implementing dynamic_action_selection -} - -/* --------------------------------------------------------------------- */ -/** - * Cloning methods - */ -enum CloneMethod_t { - /// Clone method Packet source Insertion point - Ingress2Ingress, /// original ingress, Ingress parser - Ingres2Egress, /// post parse original ingres, Buffering queue - Egress2Ingress, /// post deparse in egress, Ingress parser - Egress2Egress /// inout to deparser in egress, Buffering queue -} - -/* --------------------------------------------------------------------- */ -/* - * PSA Externs - */ - -/** - * The PacketReplicationEngine extern represents the non-programmable - * part of the PSA pipeline. - * - * Even though the PRE can not be programmed using P4, it can be - * configured both directly using control plane APIs and by setting - * intrinsic metadata. In this specification we opt to define the - * operations available in the PRE as method invocations. A target - * backend is responsible for mapping the PRE extern APIs to the - * appropriate mechanisms for performing these operations in the - * hardware. - * - * The PRE is instantiated by the architecture and a P4 program can - * use it directly. It is an error to instantiate the PRE multiple - * times. The PRE is made available to the Ingress and Egress - * programmable blocks using the same mechanism as packet_in. - * - * Note: some of these operations may not be implemented as primitive - * operations on a certain target. However, All of the operations can - * be implemented as a combination of other operations. Applications - * that rely on non-primitive operations may incur significant - * performance penalties, however, they should be functionally - * correct. - * - * Alternatively, we can consider a design in which we split the PRE - * (and the associated functionality) between an ingress PRE extern - * and a egress BQE (Buffering and Queueing Engine) extern. That - * decision will be finalized based on application needs. - * - * Semantics of behavior for multiple calls to PRE APIs - * - * - multiple calls to send_to_port -- the last call in the ingress - * pipeline sets the output port. - * - * - multiple calls to multicast -- the last in the ingress pipeline - * sets the multicast group - * - * - interleaving send_to_port and multicast -- the semantics of multicast - * is defined as below (https://github.com/p4lang/tutorials/issues/22): - * if (multicast_group != 0) - * multicast_to_group(multicast_group); - * else - * send_to_port(multicast_port); - * From this, it follows that if there is a call that sets the - * multicast_group, the packet will be multicast to the group that - * last set the multicast group. Otherwise, the packet will be sent to - * the port set by either send_to_port or multicast invocation. - * - * - any call to drop in the pipeline will cause the packet to drop - * - * - how do we drop clone packets? - * ... - * - * \TODO: finalize the semantics of calling multiple of the PRE APIs - * - */ -extern PacketReplicationEngine { - - // PacketReplicationEngine(); /// No constructor. PRE is instantiated - /// by the architecture. - - /// Unicast operation: sends packet to port - /// - /// Targets may implement this operation by setting the appropriate - /// intrinsic metadata or through some other mechanism of - /// configuring the PRE. - /// - /// @param port The output port. If the port is PORT_CPU the packet - /// will be sent to CPU - void send_to_port (in PortId_t port); - - /// Multicast operation: sends packet to a multicast group or a port - /// - /// Targets may implement this operation by setting the appropriate - /// intrinsic metadata or through some other mechanism of - /// configuring the PRE. - /// - /// @param multicast_group Multicast group id. The control plane - /// must program the multicast groups through a separate - /// mechanism. - /// @param port The output port. - void multicast (in MulticastGroup_t multicast_group, - in PortId_t multicast_port); - - /// Drop operation: do not forward the packet - /// - /// The PSA implements drop as an operation in the PRE. While the - /// drop operation can be invoked anywhere in the ingress pipeline, - /// the semantics supported by the PSA is that the drop will be at - /// the end of the pipeline (ingress or egress). - void drop (); - - /// Clone operation: create a copy of the packet and send it to the - /// specified port. - /// - /// The PSA specifies four types of cloning, with the packet sourced - /// from different points in the pipeline and sent back to ingress - /// or to the buffering queue in the egress (@see CloneMethod_t). - /// - /// @param clone_method The type of cloning. - /// @param port The port to send the cloned packet to. - /// - /// Note: based on discussions with Antonin, we can ignore session now - void clone (in CloneMethod_t clone_method, in PortId_t port); - - /// Clone operation: create a copy of the packet with additional - /// data and send it to the specified port. - /// - /// The PSA specifies four types of cloning, with the packet sourced - /// from different points in the pipeline and sent back to ingress - /// or to the buffering queue in the egress (@see CloneMethod_t). - /// - /// @param clone_method The type of cloning. - /// @param port The port to send the cloned packet to. - /// @param data additional header data attached to the packet - void clone (in CloneMethod_t clone_method, in PortId_t port, in T data); - - - /// Resubmit operation: send a packet to the ingress port with - /// additional data appended - /// - /// This operation is intended for recursive packet processing. - /// - /// @param data A header definition that can be added to the set of - /// packet headers. - /// @param port The input port at which the packet will be resubmitted. - void resubmit(in T data, in PortId_t port); - - /// Recirculate operation: send a post deparse packet to the ingress - /// port with additional data appended - /// - /// This operation is intended for recursive packet processing. - /// - /// @param data A header definition that can be added to the set of - /// packet headers. - /// @param port The input port at which the packet will be resubmitted. - void recirculate(in T data, in PortId_t port); - - /// Truncate operation - /// - /// Truncate the outgoing packet to the specified length - /// - /// @param length packet length - void truncate(in bit<32> length); - - /* - @ControlPlaneAPI - { - // TBD - } - */ -} - -/* --------------------------------------------------------------------- */ -/* - * Hashes - */ - -/// Supported hash algorithms -enum HashAlgorithm { - crc32, - crc32_custom, - crc16, - crc16_custom, - random, - identity -} - -/// Hash function -/// -/// @param Algo The algorithm to use for computation (@see HashAlgorithm). -/// @param O The type of the return value of the hash. -/// -/// Example usage: -/// parser P() { -/// Hash> h(); -/// bit<56> hash_value = h.getHash(16, buffer, 100); -/// ... -/// } -extern Hash { - /// Constructor - Hash(); - - /// compute the hash for data - O getHash(in T base, in D data, in M max); - - /* - @ControlPlaneAPI - { } - */ -} - -/* --------------------------------------------------------------------- */ -/// Checksum computation -/// -/// @param W The width of the checksum -extern Checksum { - Checksum(HashAlgorithm hash); /// constructor - void clear(); /// prepare unit for computation - void update(in T data); /// add data to checksum - void remove(in T data); /// remove data from existing checksum - W get(); /// get the checksum for data added since last clear - - /* - @ControlPlaneAPI - { } - */ -} - -/* --------------------------------------------------------------------- */ -/** - * Counters - * - * Counters are a simple mechanism for keeping statistics about the - * packets that trigger a table in a Match Action unit. - * - * Direct counters fire when the count method is ivoked in an action, and - * have an instance for each entry in the table. - */ - -/// Counter types -enum CounterType_t { - packets, - bytes, - packets_and_bytes -} - -/// Counter: RFC-XXXX -extern Counter { - Counter(S n_counters, W size_in_bits, CounterType_t counter_type); - void count(in S index, in W increment); - - /* - @ControlPlaneAPI - { - W read (in S index); - W sync_read (in S index); - void set (in S index, in W seed); - void reset (in S index); - void start (in S index); - void stop (in S index); - } - */ -} - -/// DirectCounter: RFC-XXXX -extern DirectCounter { - DirectCounter(entry_key key, CounterType_t counter_type); - void count(); - - /* - @ControlPlaneAPI - { - W read (in entry_key key); - W sync_read (in entry_key key); - void set (in W seed); - void reset (in entry_key key); - void start (in entry_key key); - void stop (in entry_key key); - } - */ -} - -/* --------------------------------------------------------------------- */ -/** - * Meters: RFC 2698 - * - * Meters are a more complex mechanism for keeping statistics about - * the packets that trigger a table. The meters specified in the PSA - * are 3-color meters. - */ - -/// Meter types -enum MeterType_t { - packets, - bytes -} -/// Meter colors -enum MeterColor_t { RED, GREEN, YELLOW }; - -/// Meter -extern Meter { - Meter(S n_meters, MeterType_t type); - MeterColor_t execute(in S index, in MeterColor_t color); - - /* - @ControlPlaneAPI - { - reset(in MeterColor_t color); - setParams(in S committedRate, out S committedBurstSize - in S peakRate, in S peakBurstSize); - getParams(out S committedRate, out S committedBurstSize - out S peakRate, out S peakBurstSize); - } - */ -} - -/// DirectMeter -extern DirectMeter { - DirectMeter(MeterType_t type); - MeterColor_t execute(in MeterColor_t color); - - /* - @ControlPlaneAPI - { - reset(in MeterColor_t color); - void setParams(in S committedRate, out S committedBurstSize - in S peakRate, in S peakBurstSize); - void getParams(out S committedRate, out S committedBurstSize - out S peakRate, out S peakBurstSize); - } - */ -} - -/* --------------------------------------------------------------------- */ -/** - * Registers - * - * Registers are stateful memories whose values can be read and - * written in actions. Registers are similar to counters, but can be - * used in a more general way to keep state. - * - * Although registers cannot be used directly in matching, they may be - * used as the RHS of an assignment operation, allowing the current - * value of the register to be copied into metadata and be available - * for matching in subsquent tables. - */ -extern Register { - Register(S size); - T read (in S index); - void write (in S index, in T value); - - /* - @ControlPlaneAPI - { - T read (in S index); - void set (in S index, in T seed); - void reset (in S index); - } - */ -} - -/* --------------------------------------------------------------------- */ -/** - * Random - * - * The random extern provides a reliable, target specific number generator - * in the min .. max range. - */ - -/// The set of distributions supported by the Random extern. -enum RandomDistribution { - PRNG, - Binomial, - Poisson -} - -extern Random { - Random(RandomDistribution dist, T min, T max); - T read(); - - /* - @ControlPlaneAPI - { - void reset(); - void setSeed(in T seed); - } - */ -} - -/* --------------------------------------------------------------------- */ -/** - * Action profiles are used as table implementation attributes - * - * Action profiles implement a mechanism to populate table entries - * with actions and action data. The only data plane operation - * required is to instantiate this extern. When the control plane adds - * entries (members) into the extern, they are essentially populating - * the corresponding table entries. - */ -extern ActionProfile { - /// Construct an action profile of 'size' entries - ActionProfile(bit<32> size); - - /* - @ControlPlaneAPI - { - entry_handle add_member (action_ref, action_data); - void delete_member (entry_handle); - entry_handle modify_member (entry_handle, action_ref, action_data); - } - */ -} - -/** - * Action selectors are used as table implementation attributes - * - * Action selectors implement another mechanism to populate table - * entries with actions and action data. They are similar to action - * profiles, with additional support to define groups of - * entries. Action selectors require a hash algorithm to select - * members in a group. The only data plane operation required is to - * instantiate this extern. When the control plane adds entries - * (members) into the extern, they are essentially populating the - * corresponding table entries. - */ -extern ActionSelector { - /// Construct an action selector of 'size' entries - /// @param algo hash algorithm to select a member in a group - /// @param size number of entries in the action selector - /// @param outputWidth size of the key - ActionSelector(HashAlgorithm algo, bit<32> size, bit<32> outputWidth); - - /* - @ControlPlaneAPI - { - entry_handle add_member (action_ref, action_data); - void delete_member (entry_handle); - entry_handle modify_member (entry_handle, action_ref, action_data); - group_handle create_group (); - void delete_group (group_handle); - void add_to_group (group_handle, entry_handle); - void delete_from_group (group_handle, entry_handle); - } - */ -} - - -/* --------------------------------------------------------------------- */ -/// \TODO: is generating a new packet and sending it to the stream or is -/// it adding a header to the current packet and sending it to the -/// stream (copying or redirecting). -extern Digest { - Digest(PortId_t receiver); /// define a digest stream to receiver - void emit(in T data); /// emit data into the stream - - /* - @ControlPlaneAPI - { - // TBD - // If the type T is a named struct, the name should be used - // to generate the control-plane API. - } - */ -} - -/* --------------------------------------------------------------------- */ -/** - * Programmable blocks - * - * The following declarations provide a template for the programmable - * blocks in the PSA. The P4 programmer is responsible for - * implementing controls that match these interfaces and instantiate - * them in a package definition. - */ - -parser Parser(packet_in buffer, out H parsed_hdr, inout M user_meta, - in psa_parser_input_metadata_t istd); - -control VerifyChecksum(in H hdr, inout M user_meta); - -control Ingress(inout H hdr, inout M user_meta, - PacketReplicationEngine pre, - in psa_ingress_input_metadata_t istd, - out psa_ingress_output_metadata_t ostd); - -control Egress(inout H hdr, inout M user_meta, - PacketReplicationEngine pre, - in psa_egress_input_metadata_t istd); - -control ComputeChecksum(inout H hdr, inout M user_meta); - -@deparser -control Deparser(packet_out buffer, in H hdr); - - -package PSA_Switch(Parser p, - VerifyChecksum vr, - Ingress ig, - Egress eg, - ComputeChecksum ck, - Deparser dep); - -#endif /* _PORTABLE_SWITCH_ARCHITECTURE_P4_ */ diff --git a/examples/docs/includes/v1model.p4 b/examples/docs/includes/v1model.p4 deleted file mode 100644 index bce7e96..0000000 --- a/examples/docs/includes/v1model.p4 +++ /dev/null @@ -1,254 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -/* P4-16 declaration of the P4 v1.0 switch model */ - -#ifndef _V1_MODEL_P4_ -#define _V1_MODEL_P4_ - -#include "core.p4" - -match_kind { - range, - // Used for implementing dynamic_action_selection - selector -} - -// Are these correct? -@metadata @name("standard_metadata") -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; - // - // @alias is used to generate the field_alias section of the BMV2 JSON. - // Field alias creates a mapping from the metadata name in P4 program to - // the behavioral model's internal metadata name. Here we use it to - // expose all metadata supported by simple switch to the user through - // standard_metadata_t. - // - // flattening fields that exist in bmv2-ss - // queueing metadata - @alias("queueing_metadata.enq_timestamp") bit<32> enq_timestamp; - @alias("queueing_metadata.enq_qdepth") bit<19> enq_qdepth; - @alias("queueing_metadata.deq_timedelta") bit<32> deq_timedelta; - @alias("queueing_metadata.deq_qdepth") bit<19> deq_qdepth; - // intrinsic metadata - @alias("intrinsic_metadata.ingress_global_timestamp") bit<48> ingress_global_timestamp; - @alias("intrinsic_metadata.egress_global_timestamp") bit<48> egress_global_timestamp; - @alias("intrinsic_metadata.lf_field_list") bit<32> lf_field_list; - @alias("intrinsic_metadata.mcast_grp") bit<16> mcast_grp; - @alias("intrinsic_metadata.resubmit_flag") bit<32> resubmit_flag; - @alias("intrinsic_metadata.recirculate_flag") bit<32> recirculate_flag; - @alias("intrinsic_metadata.egress_rid") bit<16> egress_rid; - /// Indicates that a verify_checksum() method has failed. - bit<1> checksum_error; - - //Priority queueing - @alias("queueing_metadata.qid") bit<5> qid; - @alias("intrinsic_metadata.priority") bit<3> priority; - -} - -enum CounterType { - packets, - bytes, - packets_and_bytes -} - -enum MeterType { - packets, - bytes -} - -extern counter { - counter(bit<32> size, CounterType type); - void count(in bit<32> index); -} - -extern direct_counter { - direct_counter(CounterType type); - void count(); -} - -extern meter { - meter(bit<32> size, MeterType type); - void execute_meter(in bit<32> index, out T result); -} - -extern direct_meter { - direct_meter(MeterType type); - void read(out T result); -} - -extern register { - register(bit<32> size); - void read(out T result, in bit<32> index); - void write(in bit<32> index, in T value); -} - -// used as table implementation attribute -extern action_profile { - action_profile(bit<32> size); -} - -// Get a random number in the range lo..hi -extern void random(out T result, in T lo, in T hi); -// If the type T is a named struct, the name is used -// to generate the control-plane API. -extern void digest(in bit<32> receiver, in T data); - -enum HashAlgorithm { - crc32, - crc32_custom, - crc16, - crc16_custom, - random, - identity, - csum16, - xor16 -} - -extern void mark_to_drop(); -extern void hash(out O result, in HashAlgorithm algo, in T base, in D data, in M max); - -extern action_selector { - action_selector(HashAlgorithm algorithm, bit<32> size, bit<32> outputWidth); -} - -enum CloneType { - I2E, - E2E -} - -@deprecated("Please use verify_checksum/update_checksum instead.") -extern Checksum16 { - Checksum16(); - bit<16> get(in D data); -} - -/** -Verifies the checksum of the supplied data. -If this method detects that a checksum of the data is not correct it -sets the standard_metadata checksum_error bit. -@param T Must be a tuple type where all the fields are bit-fields or varbits. - The total dynamic length of the fields is a multiple of the output size. -@param O Checksum type; must be bit type. -@param condition If 'false' the verification always succeeds. -@param data Data whose checksum is verified. -@param checksum Expected checksum of the data; note that is must be a left-value. -@param algo Algorithm to use for checksum (not all algorithms may be supported). - Must be a compile-time constant. -*/ -extern void verify_checksum(in bool condition, in T data, inout O checksum, HashAlgorithm algo); -/** -Computes the checksum of the supplied data. -@param T Must be a tuple type where all the fields are bit-fields or varbits. - The total dynamic length of the fields is a multiple of the output size. -@param O Output type; must be bit type. -@param condition If 'false' the checksum is not changed -@param data Data whose checksum is computed. -@param checksum Checksum of the data. -@param algo Algorithm to use for checksum (not all algorithms may be supported). - Must be a compile-time constant. -*/ -extern void update_checksum(in bool condition, in T data, inout O checksum, HashAlgorithm algo); - -/** -Verifies the checksum of the supplied data including the payload. -The payload is defined as "all bytes of the packet which were not parsed by the parser". -If this method detects that a checksum of the data is not correct it -sets the standard_metadata checksum_error bit. -@param T Must be a tuple type where all the fields are bit-fields or varbits. - The total dynamic length of the fields is a multiple of the output size. -@param O Checksum type; must be bit type. -@param condition If 'false' the verification always succeeds. -@param data Data whose checksum is verified. -@param checksum Expected checksum of the data; note that is must be a left-value. -@param algo Algorithm to use for checksum (not all algorithms may be supported). - Must be a compile-time constant. -*/ -extern void verify_checksum_with_payload(in bool condition, in T data, inout O checksum, HashAlgorithm algo); -/** -Computes the checksum of the supplied data including the payload. -The payload is defined as "all bytes of the packet which were not parsed by the parser". -@param T Must be a tuple type where all the fields are bit-fields or varbits. - The total dynamic length of the fields is a multiple of the output size. -@param O Output type; must be bit type. -@param condition If 'false' the checksum is not changed -@param data Data whose checksum is computed. -@param checksum Checksum of the data. -@param algo Algorithm to use for checksum (not all algorithms may be supported). - Must be a compile-time constant. -*/ -extern void update_checksum_with_payload(in bool condition, in T data, inout O checksum, HashAlgorithm algo); - -extern void resubmit(in T data); -extern void recirculate(in T data); -extern void clone(in CloneType type, in bit<32> session); -extern void clone3(in CloneType type, in bit<32> session, in T data); - -extern void truncate(in bit<32> length); - -// The name 'standard_metadata' is reserved - -// Architecture. -// M should be a struct of structs -// H should be a struct of headers or stacks - -parser Parser(packet_in b, - out H parsedHdr, - inout M meta, - inout standard_metadata_t standard_metadata); - -/* The only legal statements in the implementation of the -VerifyChecksum control are: block statements, calls to the -verify_checksum and verify_checksum_with_payload methods, -and return statements. */ -control VerifyChecksum(inout H hdr, - inout M meta); -@pipeline -control Ingress(inout H hdr, - inout M meta, - inout standard_metadata_t standard_metadata); -@pipeline -control Egress(inout H hdr, - inout M meta, - inout standard_metadata_t standard_metadata); - -/* The only legal statements in the implementation of the -ComputeChecksum control are: block statements, calls to the -update_checksum and update_checksum_with_payload methods, -and return statements. */ -control ComputeChecksum(inout H hdr, - inout M meta); -@deparser -control Deparser(packet_out b, in H hdr); - -package V1Switch(Parser p, - VerifyChecksum vr, - Ingress ig, - Egress eg, - ComputeChecksum ck, - Deparser dep - ); - -#endif /* _V1_MODEL_P4_ */ \ No newline at end of file diff --git a/examples/docs/migration-guide.pptx b/examples/docs/migration-guide.pptx deleted file mode 100644 index a1ce788..0000000 Binary files a/examples/docs/migration-guide.pptx and /dev/null differ diff --git a/examples/docs/p4-mode.el b/examples/docs/p4-mode.el deleted file mode 100644 index 77ebe56..0000000 --- a/examples/docs/p4-mode.el +++ /dev/null @@ -1,28 +0,0 @@ -;;; p4-mode.el --- Support for the P4 programming language - -;; Copyright (C) 2016- Barefoot Networks -;; Author: Vladimir Gurevich -;; Maintainer: Vladimir Gurevich -;; Created: 21 Jan 2016 -;; Version: 1.0 -;; Keywords: languages p4 -;; Homepage: http://p4.org - -;; This file is not part of GNU Emacs. - -;; This file is free software… - -;; Given two different versions of P4 language, P4_14 and P4_16 I decided to -;; split P4 mode into two separate ones: P4_14 and P4_16 -;; -;; This file therefore will load both modes and then the user can choose them -;; by using Emacs mode line. Unfortunately, at least for now, P4 programs have -;; the same extension (.p4) regardless of the version of the language. I would -;; recommend associating this extension with the mode you use most, while -;; getting into the habit of starting .p4 files with the mode line, e.g. -;; -;; /* -*- mode: P4_16 -*- */ - -(load "p4_14-mode") -(load "p4_16-mode") - diff --git a/examples/docs/p4_14-mode.el b/examples/docs/p4_14-mode.el deleted file mode 100644 index 282bb42..0000000 --- a/examples/docs/p4_14-mode.el +++ /dev/null @@ -1,264 +0,0 @@ -;;; p4_14-mode.el --- Support for the P4_14 programming language - -;; Copyright (C) 2016- Barefoot Networks -;; Author: Vladimir Gurevich -;; Maintainer: Vladimir Gurevich -;; Created: 21 Jan 2016 -;; Version: 1.0 -;; Keywords: languages p4_14 -;; Homepage: http://p4_14.org - -;; This file is not part of GNU Emacs. - -;; This file is free software… - -;; Placeholder for user customization code -(defvar p4_14-mode-hook nil) - -(defun p4_14-electric-brace (arg) - "Insert a brace." - (interactive "*P") - (self-insert-command (prefix-numeric-value arg)) - (save-excursion - (move-beginning-of-line nil) - (indent-for-tab-command))) - -;; Define the keymap (for now it is pretty much default) -(defvar p4_14-mode-map - (let ((map (make-keymap))) - (define-key map "\C-j" 'newline-and-indent) - (define-key map "{" 'p4_14-electric-brace) - (define-key map "}" 'p4_14-electric-brace) - (define-key map "\C-c\C-c" 'comment-region) - map) - "Keymap for P4_14 major mode") - -;; Syntactic HighLighting - -;; Main keywors (declarations and operators) -(setq p4_14-keywords - '("action" "action_profile" "apply" "attribute" - "blackbox" "blackbox_type" - "calculated_field" "counter" "control" "default" - "else" "extern" "extern_type" "extract" - "field_list" "field_list_calculation" "header" "header_type" - "if" "hit" "metadata" "meter" "method" "miss" - "parser" "parser_drop" "parser_exception" "parser_value_set" - "register" - "return" "select" "table" - )) - -(setq p4_14-pragma - '("@pragma") - ) - -(setq p4_14-attributes - '("actions" "action_selector" "algorithm" "attributes" - "direct" "dynamic_action_selection" - "fields" - "default_action" "support_timeout" - "size" "max_size" "min_size" - "in" "inout" "out" "input" "instance_count" - "layout" "output_width" "reads" - "update" "verify" - "witdh" "min_width" - "optional" - "type" - "reg" - "writes" - "expression_local_variables" - ;;; stateful_apu_blackbox-specific attributes - "update_lo_1_value" "update_lo_2_value" - "update_hi_1_value" "update_hi_2_value" - "update_lo_1_predicate" "update_lo_2_predicate" - "update_hi_1_predicate" "update_hi_2_predicate" - "output_value" "output_predicate" "output_dst" - "initial_register_lo_value" "initial_register_hi_value" - "selector_binding" - "math_unit_input" "math_unit_output_scale" - "math_unit_exponent_shift" "math_unit_exponent_invert" - "math_unit_lookup_table" - "reduction_or_group" - "stateful_logging_mode" - ;;; lpf-specific attributes - "filter_input" - ;;; wred-specific attributes - "wred_input" - )) - -(setq p4_14-variables - '( - ;;; stateful_apu_blackbox-specific variables - "alu_lo" "alu_hi" - "register_lo" "register_hi" - "math_unit" - "condition_lo" "condition_hi" "predicate" "combined_predicate" - "output_value" "output_predicate" "output_dst" - ;;; lpf-specific variables - "filter_input" - ;;; wred-specific attributes - "wred_input")) - -(setq p4_14-operations - '("and" "or" "not")) - -(setq p4_14-constants - '("false" "true" "static" "dynamic" - "exact" "ternary" "valid" "range" - "bytes" "packets")) - -(setq p4_14-types - '("bit" "int" "saturated" "signed" "string" "expression")) - -(setq p4_14-primitives - '("add_header" "remove_header" "copy_header" "push" "pop" - "no_op" "drop" - "add" "add_to_field" "subtract" - "bit_and" "bit_andca" "bit_andcb" - "bit_or" "bit_orca" "bit_orcb" - "bit_xor" "bit_xnor" "bit_nand" "bit_nor" - "bit_not" - "bypass_egress" - "exit" - "funnel_shift_right" - "invalidate" - "mark_for_drop" - "max" "min" - "execute_stateful_alu" "execute_stateful_alu_from_hash" - "execute_stateful_log" - "modify_field_with_hash_based_offset" - "modify_field_with_rng_uniform" - "resubmit" - "clone_ingress_pkt_to_egress" "clone_i2e" - "clone_egress_pkt_to_egress" "clone_e2e" - "recirculate" - "generate_digest" - "set_metadata" "modify_field" - "count" "execute_meter" - "read_bit" "read_bitc" "set_bit" "set_bitc" "clr_bit" "clr_bitc")) - -(setq p4_14-cpp - '("#include" - "#define" "#undef" - "#if" "#ifdef" "#ifndef" - "#elif" "#else" - "#endif" - "defined" - "#line" "#file")) - -(setq p4_14-cppwarn - '("#error" "#warning")) - -;; Optimize the strings -(setq p4_14-keywords-regexp (regexp-opt p4_14-keywords 'words)) -(setq p4_14-pragma-regexp (regexp-opt p4_14-pragma 1)) -(setq p4_14-attributes-regexp (regexp-opt p4_14-attributes 'words)) -(setq p4_14-variables-regexp (regexp-opt p4_14-variables 'words)) -(setq p4_14-operations-regexp (regexp-opt p4_14-operations 'words)) -(setq p4_14-constants-regexp (regexp-opt p4_14-constants 'words)) -(setq p4_14-types-regexp (regexp-opt p4_14-types 'words)) -(setq p4_14-primitives-regexp (regexp-opt p4_14-primitives 'words)) -(setq p4_14-cpp-regexp (regexp-opt p4_14-cpp 1)) -(setq p4_14-cppwarn-regexp (regexp-opt p4_14-cppwarn 1)) - - -;; create the list for font-lock. -;; each category of keyword is given a particular face -(defconst p4_14-font-lock-keywords - (list - (cons p4_14-cpp-regexp font-lock-preprocessor-face) - (cons p4_14-cppwarn-regexp font-lock-warning-face) - (cons p4_14-types-regexp font-lock-type-face) - (cons p4_14-constants-regexp font-lock-constant-face) - (cons p4_14-attributes-regexp font-lock-builtin-face) - (cons p4_14-variables-regexp font-lock-variable-name-face) - (cons p4_14-primitives-regexp font-lock-function-name-face) - (cons p4_14-operations-regexp font-lock-builtin-face) - (cons p4_14-keywords-regexp font-lock-keyword-face) - (cons p4_14-pragma-regexp font-lock-keyword-face) - (cons "\\(\\w*_t +\\)" font-lock-type-face) - (cons "\\(<[^>]+>\\)" font-lock-string-face) - (cons "\\([^_A-Za-z]0x[0-9A-Fa-f]+\\)" font-lock-constant-face) - (cons "\\([^_A-Za-z]0b[01]+\\)" font-lock-constant-face) - (cons "\\([^_A-Za-z][+-]?[0-9]+\\)" font-lock-constant-face) -;; (cons "\\(\\w*\\)" font-lock-variable-name-face) - ) - "Default Highlighting Expressions for P4_14") - -(defvar p4_14-mode-syntax-table - (let ((st (make-syntax-table))) - (modify-syntax-entry ?_ "w" st) - (modify-syntax-entry ?/ ". 124b" st) - (modify-syntax-entry ?* ". 23" st) - (modify-syntax-entry ?\n "> b" st) - st) - "Syntax table for p4_14-mode") - -;;; Indentation -(defvar p4_14-indent-offset 4 - "Indentation offset for `p4_14-mode'.") - -(defun p4_14-indent-line () - "Indent current line for any balanced-paren-mode'." - (interactive) - (let ((indent-col 0) - (indentation-increasers "[{(]") - (indentation-decreasers "[})]") - ) - (save-excursion - (beginning-of-line) - (condition-case nil - (while t - (backward-up-list 1) - (when (looking-at indentation-increasers) - (setq indent-col (+ indent-col p4_14-indent-offset)))) - (error nil))) - (save-excursion - (back-to-indentation) - (when (and (looking-at indentation-decreasers) - (>= indent-col p4_14-indent-offset)) - (setq indent-col (- indent-col p4_14-indent-offset)))) - (indent-line-to indent-col))) - -;;; Imenu support -(require 'imenu) -(setq p4_14-imenu-generic-expression - '( - ("Controls" "^control *\\([A-Za-z0-9_]*\\)" 1) - ("Externs" "^blackbox *\\([A-Za-z0-9_]*\\) *\\([A-Za-z0-9_]*\\)" 2) - ("Registers" "^register *\\([A-Za-z0-9_]*\\)" 1) - ("Meters" "^meter *\\([A-Za-z0-9_]*\\)" 1) - ("Counters" "^counter *\\([A-Za-z0-9_]*\\)" 1) - ("Tables" "^table *\\([A-Za-z0-9_]*\\)" 1) - ("Actions" "^action *\\([A-Za-z0-9_]*\\)" 1) - ("Parser States" "^parser *\\([A-Za-z0-9_]*\\)" 1) - ("Header Types" "^header_type *\\([A-Za-z0-9_]*\\)" 1) - )) - -;;; Cscope Support -(require 'xcscope) - -;; Put everything together -(defun p4_14-mode () - "Major mode for editing P4_14 programs" - (interactive) - (kill-all-local-variables) - (set-syntax-table p4_14-mode-syntax-table) - (use-local-map p4_14-mode-map) - (set (make-local-variable 'font-lock-defaults) '(p4_14-font-lock-keywords)) - (set (make-local-variable 'indent-line-function) 'p4_14-indent-line) - (setq major-mode 'p4_14-mode) - (setq mode-name "P4_14") - (setq imenu-generic-expression p4_14-imenu-generic-expression) - ;; Setting this to nil causes indentation to use only space - ;; characters, never tabs. - (setq indent-tabs-mode nil) - (setq comment-start "// ") - (setq comment-end "") - (imenu-add-to-menubar "P4_14") - (cscope-minor-mode) - (run-hooks 'p4_14-mode-hook) -) - -;; The most important line -(provide 'p4_14-mode) diff --git a/examples/docs/p4_16-mode.el b/examples/docs/p4_16-mode.el deleted file mode 100644 index 5e30440..0000000 --- a/examples/docs/p4_16-mode.el +++ /dev/null @@ -1,238 +0,0 @@ -;;; p4_16-mode.el --- Support for the P4_16 programming language - -;; Copyright (C) 2016- Barefoot Networks -;; Author: Vladimir Gurevich -;; Maintainer: Vladimir Gurevich -;; Created: 15 April 2017 -;; Version: 0.2 -;; Keywords: languages p4_16 -;; Homepage: http://p4.org - -;; This file is not part of GNU Emacs. - -;; This file is free software… - -;; This mode has preliminary support for P4_16. It covers the core language, -;; but it is not clear yet, how we can highlight the indentifiers, defined -;; for a particular architecture. Core library definitions are included - -;; Placeholder for user customization code -(defvar p4_16-mode-hook nil) - -(defun p4_16-electric-brace (arg) - "Insert a brace." - (interactive "*P") - (self-insert-command (prefix-numeric-value arg)) - (save-excursion - (move-beginning-of-line nil) - (indent-for-tab-command))) - -;; Define the keymap (for now it is pretty much default) -(defvar p4_16-mode-map - (let ((map (make-keymap))) - (define-key map "\C-j" 'newline-and-indent) - (define-key map "{" 'p4_16-electric-brace) - (define-key map "}" 'p4_16-electric-brace) - (define-key map "\C-c\C-c" 'comment-region) - map) - "Keymap for P4_16 major mode") - -;; Syntactic HighLighting - -;; Main keywors (declarations and operators) -(setq p4_16-keywords - '("action" "apply" - "control" - "default" - "else" "enum" "extern" "exit" - "header" "header_union" - "if" - "match_kind" - "package" "parser" - "return" - "select" "state" "struct" "switch" - "table" "transition" "tuple" "typedef" - "verify" - )) - -(setq p4_16-annotations - '("@name" "@metadata" "@alias" - )) - -(setq p4_16-attributes - '("const" "in" "inout" "out" - ;; Tables - "key" "actions" "default_action" "entries" "implementation" - "counters" "meters" - )) - -(setq p4_16-variables - '("packet_in" "packet_out" - )) - -(setq p4_16-operations - '("&&&" ".." "++" "?" ":")) - -(setq p4_16-constants - '( - ;;; Don't care - "_" - ;;; bool - "false" "true" - ;;; error - "NoError" "PacketTooShort" "NoMatch" "StackOutOfBounds" - "OverwritingHeader" "HeaderTooShort" "ParserTiimeout" - ;;; match_kind - "exact" "ternary" "lpm" "range" - ;;; We can add constants for supported architectures here - )) - -(setq p4_16-types - '("bit" "bool" "int" "varbit" "void" "error" - )) - -(setq p4_16-primitives - '( - ;;; Header methods - "isValid" "setValid" "setInvalid" - ;;; Table Methods - "hit" "action_run" - ;;; packet_in methods - "extract" "lookahead" "advance" "length" - ;;; packet_out methods - "emit" - ;;; Known parser states - "accept" "reject" - ;;; misc - "NoAction" - )) - -(setq p4_16-cpp - '("#include" - "#define" "#undef" - "#if" "#ifdef" "#ifndef" - "#elif" "#else" - "#endif" - "defined" - "#line" "#file")) - -(setq p4_16-cppwarn - '("#error" "#warning")) - -;; Optimize the strings -(setq p4_16-keywords-regexp (regexp-opt p4_16-keywords 'words)) -(setq p4_16-annotations-regexp (regexp-opt p4_16-annotations 1)) -(setq p4_16-attributes-regexp (regexp-opt p4_16-attributes 'words)) -(setq p4_16-variables-regexp (regexp-opt p4_16-variables 'words)) -(setq p4_16-operations-regexp (regexp-opt p4_16-operations 'words)) -(setq p4_16-constants-regexp (regexp-opt p4_16-constants 'words)) -(setq p4_16-types-regexp (regexp-opt p4_16-types 'words)) -(setq p4_16-primitives-regexp (regexp-opt p4_16-primitives 'words)) -(setq p4_16-cpp-regexp (regexp-opt p4_16-cpp 1)) -(setq p4_16-cppwarn-regexp (regexp-opt p4_16-cppwarn 1)) - - -;; create the list for font-lock. -;; each category of keyword is given a particular face -(defconst p4_16-font-lock-keywords - (list - (cons p4_16-cpp-regexp font-lock-preprocessor-face) - (cons p4_16-cppwarn-regexp font-lock-warning-face) - (cons p4_16-types-regexp font-lock-type-face) - (cons p4_16-constants-regexp font-lock-constant-face) - (cons p4_16-attributes-regexp font-lock-builtin-face) - (cons p4_16-variables-regexp font-lock-variable-name-face) - ;;; This is a special case to distinguish the method from the keyword - (cons "\\.apply" font-lock-function-name-face) - (cons p4_16-primitives-regexp font-lock-function-name-face) - (cons p4_16-operations-regexp font-lock-builtin-face) - (cons p4_16-keywords-regexp font-lock-keyword-face) - (cons p4_16-annotations-regexp font-lock-keyword-face) - (cons "\\(\\w*_t +\\)" font-lock-type-face) - (cons "[^A-Z_][A-Z] " font-lock-type-face) ;; Total hack for templates - (cons "<[A-Z, ]*>" font-lock-type-face) - (cons "\\(<[^>]+>\\)" font-lock-string-face) - (cons "\\([^_A-Za-z]\\([0-9]+w\\)?0x[0-9A-Fa-f]+\\)" font-lock-constant-face) - (cons "\\([^_A-Za-z]\\([0-9]+w\\)?0b[01]+\\)" font-lock-constant-face) - (cons "\\([^_A-Za-z][+-]?\\([0-9]+w\\)?[0-9]+\\)" font-lock-constant-face) - ;;(cons "\\(\\w*\\)" font-lock-variable-name-face) - ) - "Default Highlighting Expressions for P4_16") - -(defvar p4_16-mode-syntax-table - (let ((st (make-syntax-table))) - (modify-syntax-entry ?_ "w" st) - (modify-syntax-entry ?/ ". 124b" st) - (modify-syntax-entry ?* ". 23" st) - (modify-syntax-entry ?\n "> b" st) - st) - "Syntax table for p4_16-mode") - -;;; Indentation -(defvar p4_16-indent-offset 4 - "Indentation offset for `p4_16-mode'.") - -(defun p4_16-indent-line () - "Indent current line for any balanced-paren-mode'." - (interactive) - (let ((indent-col 0) - (indentation-increasers "[{(]") - (indentation-decreasers "[})]") - ) - (save-excursion - (beginning-of-line) - (condition-case nil - (while t - (backward-up-list 1) - (when (looking-at indentation-increasers) - (setq indent-col (+ indent-col p4_16-indent-offset)))) - (error nil))) - (save-excursion - (back-to-indentation) - (when (and (looking-at indentation-decreasers) - (>= indent-col p4_16-indent-offset)) - (setq indent-col (- indent-col p4_16-indent-offset)))) - (indent-line-to indent-col))) - -;;; Imenu support -(require 'imenu) -(setq p4_16-imenu-generic-expression - '( - ("Controls" "^ *control +\\([A-Za-z0-9_]*\\)" 1) - ("Externs" "^ *extern +\\([A-Za-z0-9_]*\\) *\\([A-Za-z0-9_]*\\)" 2) - ("Tables" "^ *table +\\([A-Za-z0-9_]*\\)" 1) - ("Actions" "^ *action +\\([A-Za-z0-9_]*\\)" 1) - ("Parsers" "^ *parser +\\([A-Za-z0-9_]*\\)" 1) - ("Parser States" "^ *state +\\([A-Za-z0-9_]*\\)" 1) - ("Headers" "^ *header +\\([A-Za-z0-9_]*\\)" 1) - ("Header Unions" "^ *header_union +\\([A-Za-z0-9_]*\\)" 1) - ("Structs" "^ *struct +\\([A-Za-z0-9_]*\\)" 1) - )) - -;;; Cscope Support -(require 'xcscope) - -;; Put everything together -(defun p4_16-mode () - "Major mode for editing P4_16 programs" - (interactive) - (kill-all-local-variables) - (set-syntax-table p4_16-mode-syntax-table) - (use-local-map p4_16-mode-map) - (set (make-local-variable 'font-lock-defaults) '(p4_16-font-lock-keywords)) - (set (make-local-variable 'indent-line-function) 'p4_16-indent-line) - (setq major-mode 'p4_16-mode) - (setq mode-name "P4_16") - (setq imenu-generic-expression p4_16-imenu-generic-expression) - ;; Setting this to nil causes indentation to use only space - ;; characters, never tabs. - (setq indent-tabs-mode nil) - (setq comment-start "// ") - (setq comment-end "") - (imenu-add-to-menubar "P4_16") - (cscope-minor-mode) - (run-hooks 'p4_16-mode-hook) -) - -;; The most important line -(provide 'p4_16-mode) diff --git a/examples/docs/p4dbg_user_guide.md b/examples/docs/p4dbg_user_guide.md deleted file mode 100644 index 4d3bb97..0000000 --- a/examples/docs/p4dbg_user_guide.md +++ /dev/null @@ -1,282 +0,0 @@ - - -**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* - -- [P4 Debugger (p4dbg) user guide](#p4-debugger-p4dbg-user-guide) - - [List of commands](#list-of-commands) - - [General information about the debugger](#general-information-about-the-debugger) - - [The packet id](#the-packet-id) - - [Special field names](#special-field-names) - - [A more detailed list of commands](#a-more-detailed-list-of-commands) - - [`set_wp (w)`](#set_wp-w) - - [`unset_wp`](#unset_wp) - - [`show_wps`](#show_wps) - - [`break (b)`](#break-b) - - [`delete (d)`](#delete-d) - - [`show_bps`](#show_bps) - - [`continue (c)`](#continue-c) - - [`next (n)`](#next-n) - - [`print (p)`](#print-p) - - [`backtrace (bt)`](#backtrace-bt) - - [`break_packet_in`](#break_packet_in) - - [`remove_packet_in`](#remove_packet_in) - - [`stop_packet_in`](#stop_packet_in) - - [`resume_packet_in`](#resume_packet_in) - - [`filter_notifications`](#filter_notifications) - - [`reset`](#reset) - - [`skip` -- experimental](#skip----experimental) - - [`skip_all` -- experimental](#skip_all----experimental) - - [`CLI` -- experimental](#cli----experimental) - - [Future extensions](#future-extensions) - - - -# P4 Debugger (p4dbg) user guide - -## List of commands - -Here is a full list of commands with a short description. More details will be -found for each command later in this document. The last 3 commands (`skip`, -`skip_all` and `CLI`) are still experimental. - -| Command name | Short | Description | -| ---------------------- | ----- | ----------- | -| `set_wp` | `w` | Sets a watchpoint on a field | -| `unset_wp` | `N/A` | Unsets watchpoint | -| `show_wps` | `N/A` | Lists active watchpoints | -| `break` | `b` | Breaks at a specific "P4 object" | -| `delete` | `d` | Deletes breakpoint | -| `show_bps` | `N/A` | Lists active breakpoints | -| `continue` | `c` | Starts / resumes packet processing at the switch | -| `next` | `n` | Go to next update (field or “P4 context”) | -| `print` | `p` | Prints the value of a field | -| `backtrace` | `bt` | Prints a backtrace of “P4 contexts” entered by the packet | -| `break_packet_in` | `N/A` | Breaks every time a packet enters the switch | -| `remove_packet_in` | `N/A` | Undoes the break_packet_in command | -| `stop_packet_in` | `N/A` | Prevents the switch from accepting any more packets | -| `resume_packet_in` | `N/A` | Undoes the stop_packet_in command | -| `filter_notifications` | `N/A` | Restricts the received notifications to a subset of packets | -| `reset` | `N/A` | Resets all the debugger’s state | -| `skip` (exp) | `N/A` | Skips all future notifications for the current packet | -| `skip_all` (exp) | `N/A` | Skips all future notifications for the current packet and its descendants | -| `CLI` (exp) | `N/A` | Connects to the switch using the Runtime CLI and issues a command | - -## General information about the debugger - -### The packet id - -Each packet going through the switch can be identified using its "full packet -id", which is of the form `.`. Note that every time you receive an -event notification in the debugger, the packet id will be included in the -displayed message. The `` is incremented by one every time a new packet is -received by the switch. The `` is incremented by one every time a new -packet is generated by the switch in response to the same incoming packet. The -first packet received by the switch on any ingress port will have id `0.0`. The -second packet will have id `1.0`, and so on… So when is the `` ever used? -Let’s assume your target switch supports multicast and that packet `3.0` is -replicated 3 times (i.e. out of 3 different ports). Each one of these 3 copies -will receive a different ``, but the `` will remain the same. In our -case, the three full packet ids will be `3.1`, `3.2` and `3.3`. The same goes -for mirroring. - -The debugger keeps track of the "current packet id", which is the id of the last -packet for which an event notification was received by the debugger. For several -commands (e.g. `print`), the packet id can be omitted from the parameters which -will cause the debugger to use the stored "current packet id". - -### Special field names - -The debugger lets you access some special fields which are not part of the -headers or metadata. All these special names start with character `$`. We only -support one for now, `$cond`, which holds the result of the last P4 condition -evaluated by the switch. In the future, we plan on adding other such special -fields (e.g. `$action`, for the last action selected by a table lookup). Note -that all these special fields have a 32-bit width. - -## A more detailed list of commands - -### `set_wp (w)` -Usage: `set_wp ` -For example, -``` -set_wp ipv4.srcAddr -w ipv4.srcAddr -``` - -Sets a watchpoint on the provided field. For every packet, the switch will stop -running every time the field is written to, and the debugger will be -notified. Of course this does not apply to packets for which notifications are -being filtered out (see the `filter_notifications` command) or are being skipped -(see `skip` and `skip_all`). Note that a notification is generated every time a -write is done on the field, even if the field actually keeps the same value. -The field name can take the special value `$cond`, which holds the result of the -last condition evaluated. - -### `unset_wp` -Usage: `unset_wp ` -For example, -``` -unset_wp ipv4.srcAddr -``` - -Unsets a watchpoint which was previously set with the `set_wp` command. The -debugger will stop notifying the user when a write operation is performed on the -field. - -### `show_wps` -Usage: `show_wps` - -Prints a list of all the currently active watchpoints. - -### `break (b)` -Usage: `break ` -For example, -``` -break parser start -break pipeline ingress -b table ipv4_lpm -``` - -Sets a breakpoint on a given P4 object. Every time a packet is about to "enter" -this object, the switch will pause and the debugger will be notified. The valid -"p4 object types" are: parser, parse_state, pipeline, table, condition, action, -deparser. - -### `delete (d)` -Usage: `delete ` -For example, -``` -delete parser start -d pipeline ingress -``` - -Removes a breakpoint which was previously set with the break command. See -`break` command description for more details and the list of valid "p4 object -types". - -### `show_bps` -Usage: `show_bps` - -Prints a list of all the currently active breakpoints. - -### `continue (c)` -Usage: `continue` - -Starts or resumes packet processing. The switch will continue processing packet -until the next watchpoint or breakpoint event, at which point it will once again -stop all packet processing. If you forgot to set a watchpoint or breakpoint -before issuing the `continue` command you can still pause the switch by sending -an Interrupt (`Ctrl-C`) to the debugger process; you will then be able to set a -watchpoint. - -### `next (n)` -Usage: `next` - -Resumes packet processing until the next event. An event is either a field -modification or a packet entering a P4 object (e.g. a table). Unlike the -`continue` command, which will only stop the switch for watchpoints and -breakpoints set by the user, `next` will stop for all events, unless the packet -triggering this event has been explicitly excluded using the -`filter_notifications` or `skip(_all)` commands. - -### `print (p)` -Usage: `print ` - -Prints the value of a field for a given packet. The packet id needs to follow -the format `.`. If the packet id is omitted, the debugger will use the -"current packet id", which is the id of the last packet for which a notification -was received. - -### `backtrace (bt)` -Usage: `backtrace ` - -Returns the list of P4 objects that the packet is currently traversing, in -descending order. The packet id can be omitted and the "current packet id" will -be used. - -Here are examples of possible outputs: - - `parser 'parser' -> parse state 'parse_ethernet'` - - `pipeline 'ingress' -> table 'ipv4_lpm' -> action 'set_nhop'` - -### `break_packet_in` -Usage: `break_packet_in` - -When using this command, the switch will break every time a new packet is -created, unless the corresponding packet id was excluded (see -`filter_notifications`). This new packet can either be a new incoming packet -(i.e. with a new ``) or a new "copy" of the same incoming packet (i.e. same -`` but new ``). - -### `remove_packet_in` -Usage: `remove_packet_in` - -Cancels `break_packet_in`. No effect if `break_packet_in` was not previously -called. - -### `stop_packet_in` -Usage: `stop_packet_in` - -Prevents the switch from accepting any more incoming packets. Note that this -does not apply to new "copies" of a packet already being processed by the -switch. - -### `resume_packet_in` -Usage: `resume_packet_in` - -Cancels `stop_packet_in`. No effect if `stop_packet_in` was not previously -called. - -### `filter_notifications` -Usage: `filter_notifications *` -For example, -``` -filter_notifications 7.0 -filter_notifications 8.1 8.2 10.0 -filter_notifications 8 -filter_notifications 8 11.0 13 -filter_notifications -``` - -Limit the event notifications displayed by the debugger to those concerning one -of these packet ids. A packet id in the list can either be a regular full packet -id of the form `.` or simply a ``, in which case all -notifications for packets with this `` will be taken into account -(independently of the value of the ``). When `filter_notifications` is -used without any arguments (i.e. no packet ids specified), the notifications -filter will be reset and all notifications will once again be displayed by the -debugger. - -### `reset` -Usage: `reset` - -Resets all the debugger's state (e.g. watchpoints, breakpoints, notification -filters...). - -### `skip` -- experimental -Usage: `skip` - -Skips all future notifications for the "current packet id". Cannot be undone. - -### `skip_all` -- experimental -Usage: `skip_all` - -Skips all future notifications for the "current packet id" and all the packets -sharing the same ``. Cannot be undone. - -### `CLI` -- experimental -Usage: `CLI ` -For example, -``` -CLI table_dump ipv4_lpm -``` - -Opens a Thrift connection to the switch and issues a standard runtime CLI -command. Only "standard" commands are supported (no multicast PRE support). - -## Future extensions - -We are planning on supporting the following features in the future: - - support for stateful objects (meters, counters, registers) - - better P4 code integration: display current P4 code, line breakpoints - - conditional watchpoints / breakpoints (e.g. iff packet has IPv4 address - 10.0.0.1) diff --git a/examples/docs/resources.md b/examples/docs/resources.md deleted file mode 100644 index 65da417..0000000 --- a/examples/docs/resources.md +++ /dev/null @@ -1,7 +0,0 @@ -# Resources - -* [Repository](https://github.com/p4lang) -* [Official Tutorials](https://github.com/p4lang/tutorials) -* [P4-Guide](https://github.com/jafingerhut/p4-guide) -* [Presentation](https://github.com/p4lang/tutorials/blob/master/P4D2_2017_Fall/P4_tutorial_labs.pdf) -* [BMV2 Backend](https://github.com/p4lang/p4c/tree/master/backends/bmv2) \ No newline at end of file diff --git a/examples/docs/simple_switch.md b/examples/docs/simple_switch.md deleted file mode 100644 index 633983a..0000000 --- a/examples/docs/simple_switch.md +++ /dev/null @@ -1,99 +0,0 @@ -# The BMv2 Simple Switch target - -The bmv2 framework lets developpers implement their own P4-programmable -architecture as a software switch. The simple_switch architecture is the -de-facto architecture for most users, as it is roughly equivalent to the -"abstract switch model" described in the P4_14 spec. - -This document aims at providing P4 programmers with important information -regarding the simple_switch architecture. - -## Intrinsic metadata - -Each architecture usually defines its own intrinsic metadata fields, which are -used in addition to the standard metadata fields to offer more advanced -features. In the case of simple_switch, we have two separate intrinsic metadata -headers. These headers are not strictly required by the architecture as it is -possible to write a P4 program and run it through simple_switch without them -being defined. However, their presence is required to enable some features of -simple_switch. For most of these fields, there is no strict requirement as to -the bitwidth, but we recommend that you follow our suggestions below. Some of -these intrinsic metadata fields can be accessed (read and / or write) directly, -others should only be accessed through primitive actions. - -### `intrinsic_metadata` header - -We recommend that you define and instantiate this metadata header for every P4 -program that you write for the simple_switch architecture, with the following -P4-14 code: -``` -header_type intrinsic_metadata_t { - fields { - ingress_global_timestamp : 48; - lf_field_list : 8; - mcast_grp : 16; - egress_rid : 16; - resubmit_flag : 8; - recirculate_flag : 8; - } -} -metadata intrinsic_metadata_t intrinsic_metadata; -``` -- `ingress_global_timestamp`: a timestamp, in microseconds, set when the packet -shows up on ingress. The clock is set to 0 every time the switch starts. This -field can be read directly from either pipeline (ingress and egress) but should -not be written to. -- `lf_field_list`: used to store the learn id when calling `generate_digest`; do -not access directly. -- `mcast_grp`: needed for the multicast feature. This field needs to be written -in the ingress pipeline when you wish the packet to be multicast. A value of 0 -means no multicast. This value must be one of a valid multicast group configured -through bmv2 runtime interfaces. -- `egress_rid`: needed for the multicast feature. This field is only valid in -the egress pipeline and can only be read from. It is used to uniquely identify -multicast copies of the same ingress packet. -- `resubmit_flag`: should not be accessed directly. It is set by the `resubmit` -action primitive and is required for the resubmit feature. As a remainder, -`resubmit` needs to be called in the ingress pipeline. -- `recirculate_flag`: should not be accessed directly. It is set by the -`recirculate` action primitive and is required for the recirculate feature. As a -remainder, `recirculate` needs to be called from the egress pipeline. - -### `queueing_metadata` header - -You only need to define this P4 header if you want to access queueing -information - as a remainder, the packet is queued between the ingress and -egress pipelines. Note that this header is "all or nothing". Either you do not -define it or you define it with all its fields (there are 4 of them). We -recommend that you use the following P4_14 code: -``` -header_type queueing_metadata_t { - fields { - enq_timestamp : 48; - enq_qdepth : 16; - deq_timedelta : 32; - deq_qdepth : 16; - qid : 8; - } -} -metadata queueing_metadata_t queueing_metadata; -``` -Of course, all of these fields can only be accessed from the egress pipeline and -they are read-only. -- `enq_timestamp`: a timestamp, in microseconds, set when the packet is first -enqueued. -- `enq_qdepth`: the depth of the queue when the packet was first enqueued. -- `deq_timedelta`: the time, in microseconds, that the packet spent in the -queue. -- `deq_qdepth`: the depth of queue when the packet was dequeued. -- `qid`: when there are multiple queues servicing each egress port (e.g. when -priority queueing is enabled), each queue is assigned a fixed unique id, which -is written to this field. Otherwise, this field is set to 0. - -## Supported primitive actions - -We mostly support the standard P4_14 primitive actions. One difference is that -optional parameters are not supported in bmv2, so all parameters are always -required (see `resubmit` for example). -The full list of primitives can be seen in this [C++ source -file](../targets/simple_switch/primitives.cpp). diff --git a/exercises/07-Count-Min-Sketch/README.md b/exercises/07-Count-Min-Sketch/README.md index e1c3d3e..e196271 100644 --- a/exercises/07-Count-Min-Sketch/README.md +++ b/exercises/07-Count-Min-Sketch/README.md @@ -43,7 +43,7 @@ packets fast to the switch we can clone the repository again with a different na cd ~/p4-tools/ git clone https://github.com/p4lang/behavioral-model.git bmv2-opt cd bmv2-opt -git checkout 7e71a9bdd161afd63a162aaa96703bfa7ab1b3e1 +git checkout 7e71a9bdd161afd63a162aaa96703bfa7ab1b3e1 <= substitute this with the commit used in p4-learning/vm/bin/install-p4-tools.sh ./autogen.sh ./configure --disable-elogger --disable-logging-macros 'CFLAGS=-g -O2' 'CXXFLAGS=-g -O2' make -j 2 diff --git a/exercises/07-Count-Min-Sketch/solution/cm-sketch-controller.py b/exercises/07-Count-Min-Sketch/solution/cm-sketch-controller.py index 788d64d..392da55 100644 --- a/exercises/07-Count-Min-Sketch/solution/cm-sketch-controller.py +++ b/exercises/07-Count-Min-Sketch/solution/cm-sketch-controller.py @@ -90,4 +90,4 @@ def decode_registers(self, eps, n, mod, ground_truth_file="sent_flows.pickle"): controller = CMSController(args.sw) - #controller.decode_registers(args.eps, args.n, args.mod, args.flow_file) + controller.decode_registers(args.eps, args.n, args.mod, args.flow_file) diff --git a/vm/Vagrantfile b/vm/Vagrantfile index 1e0f2bf..eb17f6b 100644 --- a/vm/Vagrantfile +++ b/vm/Vagrantfile @@ -8,7 +8,7 @@ Vagrant.configure(2) do |config| # VirtualBox specific configuration config.vm.provider "virtualbox" do |vb| - vb.name = "Adv-comm-net-VM" + vb.name = "P4-learning" vb.gui = true vb.memory = 4096 vb.cpus = 3 diff --git a/vm/bin/install-p4-tools.sh b/vm/bin/install-p4-tools.sh index a403957..778bd9f 100644 --- a/vm/bin/install-p4-tools.sh +++ b/vm/bin/install-p4-tools.sh @@ -95,7 +95,7 @@ mkdir -p ${BUILD_DIR} # If false, build tools without debug features to improve throughput of BMv2 and # reduce CPU/memory footprint. DEBUG_FLAGS=true -ENABLE_P4_RUNTIME=false +ENABLE_P4_RUNTIME=true #Install Protobuf function do_protobuf { @@ -172,8 +172,12 @@ function do_sysrepo { # Dependencies in : https://github.com/p4lang/PI/blob/master/proto/README.md sudo apt-get --yes install build-essential cmake libpcre3-dev libavl-dev libev-dev libprotobuf-c-dev protobuf-c-compiler + cd ${BUILD_DIR} + # Install libyang - git clone https://github.com/CESNET/libyang.git + if [ ! -d libyang ]; then + git clone https://github.com/CESNET/libyang.git + fi cd libyang git checkout v0.16-r1 mkdir build @@ -183,8 +187,12 @@ function do_sysrepo { sudo make install sudo ldconfig + cd ../.. + # Install sysrepo - git clone https://github.com/sysrepo/sysrepo.git + if [ ! -d sysrepo ]; then + git clone https://github.com/sysrepo/sysrepo.git + fi cd sysrepo git checkout v0.7.5 mkdir build @@ -193,6 +201,7 @@ function do_sysrepo { make sudo make install sudo ldconfig + cd .. } #only if we want P4Runtime @@ -343,6 +352,14 @@ function do_install_scripts { chmod a+x /home/p4/bin/update-p4c } +function do_p4-learning { + cd ${BUILD_DIR} + if [ ! -d p4-learning ]; then + git clone https://github.com/nsg-ethz/p4-learning.git + fi + cd .. +} + do_protobuf if [ "$ENABLE_P4_RUNTIME" = true ] ; then do_grpc @@ -357,5 +374,7 @@ do_p4c do_scapy do_ptf do_p4-utils +do_install_scripts +do_p4-learning echo "Done with p4-tools install!" \ No newline at end of file diff --git a/vm/bin/misc-install.sh b/vm/bin/misc-install.sh index 7de32d4..bd9fe10 100644 --- a/vm/bin/misc-install.sh +++ b/vm/bin/misc-install.sh @@ -27,3 +27,13 @@ sudo chown p4:p4 /home/p4/.tmux.conf cd .. +# Install iperf3 (last version) + +cd /tmp +sudo apt-get remove iperf3 libiperf0 +wget https://iperf.fr/download/ubuntu/libiperf0_3.1.3-1_amd64.deb +wget https://iperf.fr/download/ubuntu/iperf3_3.1.3-1_amd64.deb +sudo dpkg -i libiperf0_3.1.3-1_amd64.deb iperf3_3.1.3-1_amd64.deb +rm libiperf0_3.1.3-1_amd64.deb iperf3_3.1.3-1_amd64.deb + +cd $HOME diff --git a/vm/bin/root-bootstrap.sh b/vm/bin/root-bootstrap.sh index 666cead..94ff1d5 100644 --- a/vm/bin/root-bootstrap.sh +++ b/vm/bin/root-bootstrap.sh @@ -67,6 +67,7 @@ sudo apt-get install -y --no-install-recommends \ libprotobuf-c-dev \ g++ \ bash-completion \ + traceroute #Install pip from source diff --git a/vm/bin/update-bmv2.sh b/vm/bin/update-bmv2.sh index 87587b3..f1e573b 100644 --- a/vm/bin/update-bmv2.sh +++ b/vm/bin/update-bmv2.sh @@ -254,8 +254,17 @@ while true ; do done # main -if [ "$ENABLE_P4_RUNTIME" == 1 ]; then - # Updates PI: https://github.com/p4lang/PI - do_update_PI + +# checks if the current path includes the word p4c somewhere +# its probably not the best way to check if we are in the right +# path, but its something +if [[ "$ROOT_PATH" == *"bmv2"* ]];then + + if [ "$ENABLE_P4_RUNTIME" == 1 ]; then + # Updates PI: https://github.com/p4lang/PI + do_update_PI + fi + do_update_bmv2 +else + die 'ERROR: you are not in a bmv2 directory' fi -do_update_bmv2 \ No newline at end of file diff --git a/vm/bin/update-p4c.sh b/vm/bin/update-p4c.sh index 9bbd3a0..89c5617 100644 --- a/vm/bin/update-p4c.sh +++ b/vm/bin/update-p4c.sh @@ -96,7 +96,7 @@ function do_update_p4c { fi make -j${NUM_CORES} - #sudo make install + sudo make install sudo ldconfig cd ../.. } @@ -155,10 +155,18 @@ while true ; do done # main -if [ "$P4INCLUDE_ONLY" == 0 ]; then - do_update_p4c -fi -if [ "$P4INCLUDE_PATH" ]; then - do_copy_p4include -fi +# checks if the current path includes the word p4c somewhere +# its probably not the best way to check if we are in the right +# path, but its something +if [[ "$ROOT_PATH" == *"p4c"* ]];then + if [ "$P4INCLUDE_ONLY" == 0 ]; then + do_update_p4c + fi + + if [ "$P4INCLUDE_PATH" ]; then + do_copy_p4include + fi +else + die 'ERROR: you are not in a p4c directory' +fi \ No newline at end of file