diff --git a/p4v1_1/env.sh b/p4v1_1/env.sh new file mode 100644 index 0000000..aedb306 --- /dev/null +++ b/p4v1_1/env.sh @@ -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 ------------------ diff --git a/p4v1_1/simple_router/README.md b/p4v1_1/simple_router/README.md new file mode 100644 index 0000000..be6cb88 --- /dev/null +++ b/p4v1_1/simple_router/README.md @@ -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`. diff --git a/p4v1_1/simple_router/add_entries.sh b/p4v1_1/simple_router/add_entries.sh new file mode 100755 index 0000000..8ce8a9a --- /dev/null +++ b/p4v1_1/simple_router/add_entries.sh @@ -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 diff --git a/p4v1_1/simple_router/commands.txt b/p4v1_1/simple_router/commands.txt new file mode 100644 index 0000000..6c959d3 --- /dev/null +++ b/p4v1_1/simple_router/commands.txt @@ -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 diff --git a/p4v1_1/simple_router/p4src/simple_router.p4 b/p4v1_1/simple_router/p4src/simple_router.p4 new file mode 100644 index 0000000..fdcb4a2 --- /dev/null +++ b/p4v1_1/simple_router/p4src/simple_router.p4 @@ -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); +} diff --git a/p4v1_1/simple_router/read_register.sh b/p4v1_1/simple_router/read_register.sh new file mode 100755 index 0000000..fcf9628 --- /dev/null +++ b/p4v1_1/simple_router/read_register.sh @@ -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 diff --git a/p4v1_1/simple_router/register_on_off.sh b/p4v1_1/simple_router/register_on_off.sh new file mode 100755 index 0000000..b70b227 --- /dev/null +++ b/p4v1_1/simple_router/register_on_off.sh @@ -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 diff --git a/p4v1_1/simple_router/run_demo.sh b/p4v1_1/simple_router/run_demo.sh new file mode 100755 index 0000000..289bc38 --- /dev/null +++ b/p4v1_1/simple_router/run_demo.sh @@ -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