Skip to content

Commit

Permalink
adding simple router example and other minor changes.
Browse files Browse the repository at this point in the history
  • Loading branch information
Muhammad Shahbaz committed Jul 7, 2016
1 parent 0a795f2 commit ee48e00
Show file tree
Hide file tree
Showing 9 changed files with 477 additions and 5 deletions.
180 changes: 175 additions & 5 deletions README.md
@@ -1,22 +1,23 @@
## PISCES Test Environment

Following provides instructions on how to setup virtual machines along with some example P4 programs.
Following provides instructions on how to setup virtual machines for the PISCES test environment along with
some example P4 programs.

### Setup Virtual Machines (VMs)

There are three virtual machines: (1) Switch, (2) Generator, and (3) Receiver. The Generator
sends traffic to the switch on switch's `eth1` interface, the switch then processes the packet
sends traffic to the switch on its `eth1` interface, the switch then processes the packet
based on the configured P4 program and sends it out to the receiver on its `eth2` interface.
The receiver receives the traffic and displays the stats on the screen.

Clone the `vagrant` repository that we have created for this setup.
Clone the `vagrant` repository.

```bash
$ git clone https://github.com/P4-vSwitch/vagrant.git
$ cd vagrant
```

And start virtual machines.
Bring up virtual machines.

```bash
$ vagrant up
Expand All @@ -26,5 +27,174 @@ $ vagrant up
## Examples

#### 1. A Layer-2 Switch
#### 1. Simple Layer-2 Switch

We show how to build a simple layer-2 switch using PISCES. We use the
[`l2_switch.p4`](https://github.com/p4lang/p4factory/tree/master/targets/l2_switch) program provided with the
[p4lang/p4factory](https://github.com/p4lang/p4factory) repository.

Log into the switch VM.

```bash
$ vagrant ssh switch
```

##### a. Compiling `l2_switch.p4`

First, make sure that DPDK environment variables are populated.

```bash
$ export RTE_SDK=/home/vagrant/ovs/deps/dpdk
$ export RTE_TARGET=x86_64-native-linuxapp-gcc
$ export DPDK_DIR=$RTE_SDK
$ export DPDK_BUILD=$DPDK_DIR/$RTE_TARGET/
```

Compile the `l2_switch.p4` program. Specify **`/vagrant/examples/l2_switch/l2_switch.p4`** for the `p4inputfile` flag.

```bash
$ sudo ./configure --with-dpdk=$DPDK_BUILD CFLAGS="-g -O2 -Wno-cast-align" \
p4inputfile=/vagrant/examples/l2_switch/l2_switch.p4 \
p4outputdir=./include/p4/src
$ sudo make clean
$ sudo make -j 2
```

##### b. Running `l2_switch.p4`

###### Run `ovsdb-server`

Open a new terminal and run `ovsdb-server`.

```bash
$ cd ~/ovs/ovsdb
$ sudo ./ovsdb-server --remote=punix:/usr/local/var/run/openvswitch/db.sock \
--remote=db:Open_vSwitch,Open_vSwitch,manager_options --pidfile
```

###### Run `ovs-vswitchd`

In another terminal run `ovs-vswitchd`.

```bash
$ cd ~/ovs/vswitchd
$ sudo ./ovs-vswitchd --dpdk -c 0x1 -n 4 -- unix:/usr/local/var/run/openvswitch/db.sock --pidfile
```

###### Create an OVS bridge

In the third terminal, run the following commands to create a new OVS bridge.

```bash
$ cd ~/ovs/utilities
$ sudo ./ovs-vsctl add-br br0 -- set bridge br0 datapath_type=netdev
$ sudo ./ovs-vsctl set bridge br0 protocols=OpenFlow15
$ sudo ./ovs-vsctl add-port br0 dpdk0 -- set Interface dpdk0 type=dpdk
$ sudo ./ovs-vsctl add-port br0 dpdk1 -- set Interface dpdk1 type=dpdk
```

> Note: <br>
> This needs to be done only once. These changes persist across reboots.
>
> Also, to delete the bridge run:
> ```bash
> $ sudo ./ovs-vsctl del-br br0
> ```
>
> And to display bridge settings run:
> ```bash
> $ sudo ./ovs-vsctl show
> ```
###### Install flow rules

```bash
$ cd /vagrant/examples/l2_switch/
$ sudo ./l2_switch.sh
```

###### Send and receive test traffic

Open a new terminal and log into the generator VM.

```bash
$ vagrant ssh generator
```

Go to the `pktgen` directory.

```bash
$ cd ~/pktgen
```

Run `pktgen` as follows:

```bash
$ sudo ./app/app/x86_64-native-linuxapp-gcc/app/pktgen -c 0x3 -n 4 -- -P -m "1.0" -f /vagrant/examples/l2_switch/generator.pkt
```

Similarly, in another terminal log into the receiver VM and run `pktgen` as follows:

```bash
$ cd ~/pktgen
$ sudo ./app/app/x86_64-native-linuxapp-gcc/app/pktgen -c 0x3 -n 4 -- -P -m "1.0" -f /vagrant/examples/l2_switch/receiver.pkt
```

Now, go back to the `pktgen` interface running on the generator VM and start sending traffic.

```bash
$ start 0
```

On the receiver side, you will start seeing stats for packet RX counts on the `pktgen` interface.

> You can also verify if the switch is forwarding traffic by dumping flows on the switch VM.
> Open a new terminal and log into the switch VM.
> ```bash
> $ vagrant ssh switch
> ```
>
> Now run the following commands:
> ```
> $ cd ~/ovs/utilities
> $ sudo ./ovs-ofctl --protocols=OpenFlow15 dump-flows br0
> ```
You should see non-zero byte and packet counts in the dumped flow rules.

#### 2. Simple Router

To build a simple router, follow the same steps as above with following changes.

###### a. P4 program:

`/vagrant/examples/simple_router/simple_router.p4`

> When compiling the switch, make sure to run `sudo make clean` before running `sudo make -2`.
###### b. Flow rules:

`/vagrant/examples/simple_router/simple_router.sh`

###### c. Send and test traffic

Use the following commands on the generator VM.

```bash
$ cd ~/pktgen
$ sudo ./app/app/x86_64-native-linuxapp-gcc/app/pktgen -c 0x3 -n 4 -- -P -m "1.0" -f /vagrant/examples/simple_router/generator.pkt
```

And, the following on the receiver VM.

```bash
$ cd ~/pktgen
$ sudo ./app/app/x86_64-native-linuxapp-gcc/app/pktgen -c 0x3 -n 4 -- -P -m "1.0" -f /vagrant/examples/simple_router/receiver.pkt
```

---

Enjoy!

For more information visit: <br>
**[psices.cs.princeotn.edu](psices.cs.princeotn.edu)**
1 change: 1 addition & 0 deletions examples/l2_switch/generator.pkt
@@ -0,0 +1 @@
set mac 0 08:00:27:7e:0b:95
89 changes: 89 additions & 0 deletions examples/l2_switch/l2_switch.p4
@@ -0,0 +1,89 @@
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;
}
}

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() {
}

#define MAC_LEARN_RECEIVER 1024

field_list mac_learn_digest {
ethernet_.srcAddr;
standard_metadata.ingress_port;
}

action mac_learn() {
generate_digest(MAC_LEARN_RECEIVER, mac_learn_digest);
}

table smac {
reads {
ethernet_.srcAddr : exact;
}
actions {mac_learn; _nop;}
size : 512;
}

action forward(port) {
modify_field(standard_metadata.egress_spec, port);
}

action broadcast() {
modify_field(intrinsic_metadata.mcast_grp, 1);
}

table dmac {
reads {
ethernet_.dstAddr : exact;
}
actions {forward; broadcast;}
size : 512;
}

table mcast_src_pruning {
reads {
standard_metadata.instance_type : exact;
}
actions {_nop; _drop;}
size : 1;
}

control ingress {
apply(smac);
apply(dmac);
}

control egress {
if(standard_metadata.ingress_port == standard_metadata.egress_port) {
apply(mcast_src_pruning);
}
}
25 changes: 25 additions & 0 deletions examples/l2_switch/l2_switch.sh
@@ -0,0 +1,25 @@
#! /bin/sh -ve

# Please make sure that you update the path to the current OVS directory.
DIR=~/ovs/utilities

$DIR/ovs-ofctl --protocols=OpenFlow15 del-flows br0

# SMAC Table 0
$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0 "table=0,priority=32768,ethernet__srcAddr=0x08002715b411 actions=resubmit(,1)"
$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0 "table=0,priority=32768,ethernet__srcAddr=0x0800277e0b95 actions=resubmit(,1)"
$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0 "table=0,priority=0 actions=controller"

# DMAC Table 1
$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0 "table=1,priority=32768,ethernet__dstAddr=0x08002715b411 actions=set_field:1->reg0,resubmit(,2)"
$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0 "table=1,priority=32768,ethernet__dstAddr=0x0800277e0b95 actions=set_field:2->reg0,resubmit(,2)"
$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0 "table=1,priority=0 actions=flood"

# SRC Pruning Table 2
$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0 "table=2,priority=32768,in_port=1,reg0=1 actions="
$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0 "table=2,priority=32768,in_port=2,reg0=2 actions="
$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0 "table=2,priority=32768,in_port=3,reg0=3 actions="
$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0 "table=2,priority=32768,in_port=4,reg0=4 actions="
$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0 "table=2,priority=32768,in_port=5,reg0=5 actions="
$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0 "table=2,priority=32768,in_port=6,reg0=6 actions="
$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0 "table=2,priority=0 actions=deparse,output:NXM_NX_REG0[]"
1 change: 1 addition & 0 deletions examples/l2_switch/receiver.pkt
@@ -0,0 +1 @@
set mac 0 08:00:27:15:b4:11
3 changes: 3 additions & 0 deletions examples/simple_router/generator.pkt
@@ -0,0 +1,3 @@
set mac 0 08:00:27:7e:0b:95
set ip src 0 10.0.0.14/24
set ip dst 0 10.0.0.15
3 changes: 3 additions & 0 deletions examples/simple_router/receiver.pkt
@@ -0,0 +1,3 @@
set mac 0 08:00:27:15:b4:11
set ip src 0 10.0.0.15/24
set ip dst 0 10.0.0.14

0 comments on commit ee48e00

Please sign in to comment.