From 18096531073e608acffcfe3fea2c4dc874af0b20 Mon Sep 17 00:00:00 2001 From: Antonin Bas Date: Mon, 16 Nov 2015 11:56:10 -0800 Subject: [PATCH] added a counter example --- examples/README.md | 1 + examples/counter/README.md | 14 +++++ examples/counter/commands.txt | 2 + examples/counter/p4src/counter.p4 | 92 +++++++++++++++++++++++++++++++ examples/counter/run_demo.sh | 63 +++++++++++++++++++++ examples/counter/run_switch.sh | 41 ++++++++++++++ examples/counter/send_one.py | 4 ++ 7 files changed, 217 insertions(+) create mode 100644 examples/counter/README.md create mode 100644 examples/counter/commands.txt create mode 100644 examples/counter/p4src/counter.p4 create mode 100755 examples/counter/run_demo.sh create mode 100755 examples/counter/run_switch.sh create mode 100644 examples/counter/send_one.py diff --git a/examples/README.md b/examples/README.md index 1fa1d67..b540fe7 100644 --- a/examples/README.md +++ b/examples/README.md @@ -12,6 +12,7 @@ included: - `TLV_parsing`: how to parse IPv4 options - `register`: how to use registers in P4 and read / write the state from the control plane +- `counter`: how to use counters in P4 All examples are orgranized the same way, with a `p4src` directory containing the P4 source code, and a `README` file describing the P4 program and explaining diff --git a/examples/counter/README.md b/examples/counter/README.md new file mode 100644 index 0000000..b1efeaf --- /dev/null +++ b/examples/counter/README.md @@ -0,0 +1,14 @@ +# Counter + +## Description + +This directory is a playground for counters in P4. The P4 program includes a +direct counter and an indirect counter. + +### Running the demo + +To run the demo: +- start the switch with `./run_switch.sh`, wait until `READY` is displayed. +- run the demo script with `./run_demo.sh`. The script will send packets / + display the counter values / reset the counters. Look at the script for more + details. diff --git a/examples/counter/commands.txt b/examples/counter/commands.txt new file mode 100644 index 0000000..69ba5f7 --- /dev/null +++ b/examples/counter/commands.txt @@ -0,0 +1,2 @@ +table_set_default m_table m_action +table_add m_table m_action aa:bb:cc:dd:ee:ff => 0 diff --git a/examples/counter/p4src/counter.p4 b/examples/counter/p4src/counter.p4 new file mode 100644 index 0000000..beff9c0 --- /dev/null +++ b/examples/counter/p4src/counter.p4 @@ -0,0 +1,92 @@ +/* +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 { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type intrinsic_metadata_t { + fields { + mcast_grp : 4; + egress_rid : 4; + mcast_hash : 16; + lf_field_list: 32; + } +} + +header_type meta_t { + fields { + register_tmp : 32; + } +} + +metadata meta_t meta; + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; +metadata intrinsic_metadata_t intrinsic_metadata; + +parser parse_ethernet { + extract(ethernet); + return ingress; +} + +action _drop() { + drop(); +} + +action _nop() { +} + +counter my_indirect_counter { + type: packets; + static: m_table; + instance_count: 16384; +} + +counter my_direct_counter { + type: bytes; + direct: m_table; +} + +action m_action(idx) { + count(my_indirect_counter, idx); + drop(); +} + +table m_table { + reads { + ethernet.srcAddr : exact; + } + actions { + m_action; _nop; + } + size : 16384; +} + +control ingress { + apply(m_table); +} + +control egress { +} diff --git a/examples/counter/run_demo.sh b/examples/counter/run_demo.sh new file mode 100755 index 0000000..55e7595 --- /dev/null +++ b/examples/counter/run_demo.sh @@ -0,0 +1,63 @@ +#!/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 "resetting counters" +echo "counter_reset my_indirect_counter" | $CLI_PATH counter.json +echo "counter_reset my_direct_counter" | $CLI_PATH counter.json +echo +echo +echo +echo "displaying counters [0]" +echo "counter_read my_indirect_counter 0" | $CLI_PATH counter.json +echo "counter_read my_direct_counter 0" | $CLI_PATH counter.json +echo +echo +echo +echo "sending 1 packet of size 70" +sudo python send_one.py +sleep 1 +echo +echo +echo +echo "displaying counters [0]" +echo "counter_read my_indirect_counter 0" | $CLI_PATH counter.json +echo "counter_read my_direct_counter 0" | $CLI_PATH counter.json +echo +echo +echo +echo "sending 3 packets of size 70" +sudo python send_one.py +sudo python send_one.py +sudo python send_one.py +sleep 1 +echo +echo +echo +echo "displaying counters [0]" +echo "counter_read my_indirect_counter 0" | $CLI_PATH counter.json +echo "counter_read my_direct_counter 0" | $CLI_PATH counter.json +echo +echo +echo +echo "resetting counters" +echo "counter_reset my_indirect_counter" | $CLI_PATH counter.json +echo "counter_reset my_direct_counter" | $CLI_PATH counter.json diff --git a/examples/counter/run_switch.sh b/examples/counter/run_switch.sh new file mode 100755 index 0000000..9b4c2e2 --- /dev/null +++ b/examples/counter/run_switch.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 + +P4C_BM_SCRIPT=$P4C_BM_PATH/p4c_bm/__main__.py + +SWITCH_PATH=$BMV2_PATH/targets/simple_switch/simple_switch + +CLI_PATH=$BMV2_PATH/targets/simple_switch/sswitch_CLI + +# Probably not very elegant but it works nice here: we enable interactive mode +# to be able to use fg. We start the switch in the background, sleep for 2 +# minutes to give it time to start, then add the entries and put the switch +# process back in the foreground +set -m +$P4C_BM_SCRIPT p4src/counter.p4 --json counter.json +sudo echo "sudo" > /dev/null +sudo $BMV2_PATH/targets/simple_switch/simple_switch counter.json \ + -i 0@veth0 -i 1@veth2 -i 2@veth4 -i 3@veth6 -i 4@veth8 \ + --nanolog ipc:///tmp/bm-0-log.ipc \ + --pcap & +sleep 2 +$CLI_PATH counter.json < commands.txt +echo "READY!!!" +fg diff --git a/examples/counter/send_one.py b/examples/counter/send_one.py new file mode 100644 index 0000000..ea122ca --- /dev/null +++ b/examples/counter/send_one.py @@ -0,0 +1,4 @@ +from scapy.all import * + +p = Ether(src="aa:bb:cc:dd:ee:ff") / IP(dst="10.0.1.10") / TCP() / "aaaaaaaaaaaaaaaa" +sendp(p, iface = "veth1", verbose = 0)