Merge pull request #6 from p4lang/p4v1.1

added P4v1.1 sample program with demo
This commit is contained in:
Antonin Bas 2016-02-24 13:44:51 -08:00
commit bd33b7df18
8 changed files with 361 additions and 0 deletions

8
p4v1_1/env.sh Normal file
View File

@ -0,0 +1,8 @@
THIS_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
# ---------------- EDIT THIS ------------------
BMV2_PATH=$THIS_DIR/../../bmv2
# e.g. BMV2_PATH=$THIS_DIR/../bmv2
P4C_BM_PATH=$THIS_DIR/../../p4c-bmv2
# e.g P4C_BM_PATH=$THIS_DIR/../p4c-bm
# ---------------- END ------------------

View File

@ -0,0 +1,38 @@
# P4 v1.1 Simple Router
## Description
This program is a version of the now famous simple_router program, written
according to the P4 v1.1 specification. In addition to the original
simple_router, this version can keep track of the number of IPv4 packets dropped
because of an expired TTL. This was added to illustrate some of P4 v1.1 more
advanced capabilities.
For more information on P4 v1.1, please refer to [p4.org] (http://p4.org/spec/).
Look at the [P4 program] (p4src/simple_router.p4) and observe some of the P4
v1.1 additions:
- strong typing in header type definitions and action declarations
- assignment with `=` instead of `modify_field` (extension to the v1.1 spec)
- register indexing
- support for the ternary operator (extension to the v1.1 spec)
### Running the demo
We provide a small demo to let you test the program. Before trying to run the
demo, please make sure that your [env.sh] (../env.sh) file is up-to-date.
To run the demo:
- start the switch in Mininet with `./run_switch.sh`
- in another terminal, populate the table entries with `./add_entries.sh`
- you should now be able to ping h2 from h1 by typing `h1 ping h2` in the
Mininet CLI
Once you have the basic demo running, you can start sending packets with a TTL
of 1, activate packet drop tracking in the switch and observe the count go
up. To do this:
- activate the tracking with `./register_on_off.sh on`
- send ICMP packets with a TTL of 1 from the Mininet CLI: `h1 ping h2 -t 1`. The
packets are now dropped by the switch, so you should not be able to observe a
reply
To get the drop count, simply run `./read_register.sh`.

View File

@ -0,0 +1,23 @@
#!/bin/bash
# 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_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source $THIS_DIR/../env.sh
CLI_PATH=$BMV2_PATH/targets/simple_switch/sswitch_CLI
$CLI_PATH simple_router.json < commands.txt

View File

@ -0,0 +1,10 @@
table_set_default drop_expired do_drop_expired
table_set_default send_frame _drop
table_set_default forward _drop
table_set_default ipv4_lpm _drop
table_add send_frame rewrite_mac 1 => 00:aa:bb:00:00:00
table_add send_frame rewrite_mac 2 => 00:aa:bb:00:00:01
table_add forward set_dmac 10.0.0.10 => 00:04:00:00:00:00
table_add forward set_dmac 10.0.1.10 => 00:04:00:00:00:01
table_add ipv4_lpm set_nhop 10.0.0.10/32 => 10.0.0.10 1
table_add ipv4_lpm set_nhop 10.0.1.10/32 => 10.0.1.10 2

View File

@ -0,0 +1,188 @@
/* 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.
*/
header_type ethernet_t {
fields {
bit<48> dstAddr;
bit<48> srcAddr;
bit<16> etherType;
}
}
header_type ipv4_t {
fields {
bit<4> version;
bit<4> ihl;
bit<8> diffserv;
bit<16> totalLen;
bit<16> identification;
bit<3> flags;
bit<13> fragOffset;
bit<8> ttl;
bit<8> protocol;
bit<16> hdrChecksum;
bit<32> srcAddr;
bit<32> dstAddr;
}
}
parser start {
return parse_ethernet;
}
#define ETHERTYPE_IPV4 0x0800
header ethernet_t ethernet;
parser parse_ethernet {
extract(ethernet);
return select(latest.etherType) {
ETHERTYPE_IPV4 : parse_ipv4;
default: ingress;
}
}
header ipv4_t ipv4;
field_list ipv4_checksum_list {
ipv4.version;
ipv4.ihl;
ipv4.diffserv;
ipv4.totalLen;
ipv4.identification;
ipv4.flags;
ipv4.fragOffset;
ipv4.ttl;
ipv4.protocol;
ipv4.srcAddr;
ipv4.dstAddr;
}
field_list_calculation ipv4_checksum {
input {
ipv4_checksum_list;
}
algorithm : csum16;
output_width : 16;
}
calculated_field ipv4.hdrChecksum {
verify ipv4_checksum;
update ipv4_checksum;
}
parser parse_ipv4 {
extract(ipv4);
return ingress;
}
action _drop() {
drop();
}
header_type routing_metadata_t {
fields {
bit<32> nhop_ipv4;
}
}
metadata routing_metadata_t routing_metadata;
register drops_register {
width: 32;
static: drop_expired;
instance_count: 16;
}
register drops_register_enabled {
width: 1;
static: drop_expired;
instance_count: 16;
}
action do_drop_expired() {
drops_register[0] = drops_register[0] + ((drops_register_enabled[0] == 1) ? (bit<32>)1 : 0);
drop();
}
table drop_expired {
actions { do_drop_expired; }
size: 0;
}
action set_nhop(in bit<32> nhop_ipv4, in bit<9> port) {
routing_metadata.nhop_ipv4 = nhop_ipv4;
standard_metadata.egress_spec = port;
ipv4.ttl = ipv4.ttl - 1;
}
table ipv4_lpm {
reads {
ipv4.dstAddr : lpm;
}
actions {
set_nhop;
_drop;
}
size: 1024;
}
action set_dmac(in bit<48> dmac) {
ethernet.dstAddr = dmac;
// modify_field still valid
// modify_field(ethernet.dstAddr, dmac);
}
table forward {
reads {
routing_metadata.nhop_ipv4 : exact;
}
actions {
set_dmac;
_drop;
}
size: 512;
}
action rewrite_mac(in bit<48> smac) {
ethernet.srcAddr = smac;
}
table send_frame {
reads {
standard_metadata.egress_port: exact;
}
actions {
rewrite_mac;
_drop;
}
size: 256;
}
control ingress {
if(valid(ipv4)) {
if(ipv4.ttl > 1) {
apply(ipv4_lpm);
apply(forward);
} else {
apply(drop_expired);
}
}
}
control egress {
apply(send_frame);
}

View File

@ -0,0 +1,23 @@
#!/bin/bash
# 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_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source $THIS_DIR/../env.sh
CLI_PATH=$BMV2_PATH/targets/simple_switch/sswitch_CLI
echo "register_read drops_register 0" | $CLI_PATH simple_router.json

View File

@ -0,0 +1,41 @@
#!/bin/bash
# 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_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source $THIS_DIR/../env.sh
CLI_PATH=$BMV2_PATH/targets/simple_switch/sswitch_CLI
if [ $# -lt 1 ]; then
echo "Please specify 'on' or 'off' as argument"
exit 1
fi
if [ $1 = "on" ]; then
echo "Enabling packet drop count"
v=1
elif [ $1 = "off" ]; then
echo "Disabling packet drop count"
v=0
else
echo "Invalid argument, must be one of 'on' or 'off'"
exit 1
fi
echo "register_write drops_register_enabled 0 $v" | $CLI_PATH simple_router.json
echo "Checking value..."
echo "register_read drops_register_enabled 0" | $CLI_PATH simple_router.json

View File

@ -0,0 +1,30 @@
#!/bin/bash
# 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_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source $THIS_DIR/../env.sh
P4C_BM_SCRIPT=$P4C_BM_PATH/p4c_bm/__main__.py
SWITCH_PATH=$BMV2_PATH/targets/simple_switch/simple_switch
CLI_PATH=$BMV2_PATH/tools/runtime_CLI.py
$P4C_BM_SCRIPT p4src/simple_router.p4 --json simple_router.json --p4-v1.1
sudo python $BMV2_PATH/mininet/1sw_demo.py \
--behavioral-exe $BMV2_PATH/targets/simple_switch/simple_switch \
--json simple_router.json