Run RYU Builtin App - MeshSr/ONetSwitch GitHub Wiki

Demo using the built-in application from Ryu.

Hardware - ONetSwitch30
Software - OFS-SW | OFS-HW
Controller - Ryu3.23

###Attentions & Tips

  1. Download repositories for common-bin, of-ctrl, and board specific repo, e.g. onetswitch20 or onetswitch30 or onetswitch45.
  2. Use git clone to download. DONT copy the code directly from the web page, especially when you want some pieces of Python.
  3. Run the commands from the repo-root directory that stores all the repositories above.
  4. Use sudo, this is required when extracting and copying the rootfs.
  5. Use sync, to write data buffered in memory out to disk.
  6. Clean up the SD/TF card before use.
*** example ***
user@computer-name:<repo-root>$ tree -L 1
.
├── common-bin
├── linux-meshsr
├── of-ctrl
├── ofs-hw
├── ofs-sw
├── onetswitch20
├── onetswitch30
├── onetswitch45
├── u-boot-meshsr
├── wiki
└── wiki.wiki

###OFSwitch: SD-Boot Media ####FAT Partition

  • boot.bin | devicetree.dtb | init.sh | uImage

<dir-sd-fat> is the path to the FAT partition. Typical naming could be /media/user/FAT/.

*** OFS-SW example ***
sudo cp -p common-bin/kernel/uImage <dir-sd-fat>
sudo cp -p onetswitch30/ons30-app51-ref_ofssw/ready-to-download/devicetree.dtb <dir-sd-fat>
sudo cp -p onetswitch30/ons30-app51-ref_ofssw/ready-to-download/init.sh <dir-sd-fat>
sudo cp -p onetswitch30/ons30-app51-ref_ofssw/ready-to-download/boot.bin <dir-sd-fat>
*** OFS-HW example ***
sudo cp -p common-bin/kernel/uImage <dir-sd-fat>
sudo cp -p onetswitch30/ons30-app52-ref_ofshw/ready-to-download/devicetree.dtb <dir-sd-fat>
sudo cp -p onetswitch30/ons30-app52-ref_ofshw/ready-to-download/init.sh <dir-sd-fat>
sudo cp -p onetswitch30/ons30-app52-ref_ofshw/ready-to-download/boot.bin <dir-sd-fat>

####EXT Partition

  • rootfs

<dir-rootfs-tmp> is a temp folder for the rootfs extraction, e.g. /home/user/temp/.
<dir-sd-ext> is the path to the EXT4 partition. Typical naming could be /media/user/EXT/.

*** example ***
sudo tar xzvf common-bin/rootfs/rootfs_ext4.tar.gz -C <dir-rootfs-tmp>
sudo cp -rp <dir-rootfs-tmp>/rootfs_ext4/* <dir-sd-ext>
  • lib | ofs
*** OFS-SW example ***
find common-bin/lib -name "lib*" -type f | xargs -i cp {} <dir-sd-ext>/lib/.
sudo cp -rp common-bin/ofs-sw <dir-sd-ext>/root/.
*** OFS-HW example ***
find common-bin/lib -name "lib*" -type f | xargs -i cp {} <dir-sd-ext>/lib/.
sudo cp -rp common-bin/ofs-hw <dir-sd-ext>/root/.

###IP Settings and Multi-node Scenario

  • Set different switch_ip in each init.sh if multiple nodes are used in the topo
  • Set the controller's port to controller_ip in init.sh

###OFController: Python and Ryu
####Python and the packages
We haven't checked necessity and sufficiency about the package list below. It works after all.

*** example ***
sudo apt-get install build-essential
sudo apt-get install libxml2-dev
sudo apt-get install libxslt1-dev

sudo apt-get install python-dev
sudo apt-get install python-pip
sudo apt-get install python-eventlet
sudo apt-get install python-routes
sudo apt-get install python-webob
sudo apt-get install python-paramiko
sudo apt-get install python-mysqldb
sudo apt-get install python-gevent
sudo apt-get install curl

sudo pip install --upgrade pip
sudo pip install gevent-websocket
sudo pip install flask

####Ryu and its APPs

  • Optionally, uninstall previous Ryu installation on the machine.
*** example ***
sudo pip uninstall ryu
### sudo rm -fr /usr/local/bin/ryu*
### sudo rm -fr /usr/local/lib/python2.7/dist-packages/ryu*
  • Install Ryu and copy the APPs.

<dir-ofc-exec> is the folder that hosts the Ryu controller, e.g. /home/user/ofctrl/.

*** example ***
sudo tar xzvf of-ctrl/ryu/controller/ryu-3.23.tar.gz -C <dir-ofc-exec>
sudo cp -rp of-ctrl/ryu/app/* <dir-ofc-exec>/ryu-3.23/ryu/app/.
cd <dir-ofc-exec>/ryu3.23
sudo python setup.py install

###Run simple_switch_13.py

simple_switch_13.py runs an OpenFlow 1.3 L2 self-learning switch implementation.

We've changed a little in the given simple_switch_13 by Ryu3.23, as app/msr-simple_switch/simple_switch_13.py
You can call diff to see the differences to solve some buffer handling problem.

####Steps to run

  • Setup the scenario as following.
    One host PC with Ryu, called Host-Ctrl, is connected to the ONetSwitch Zynq PS Ethernet port, in a subnet for control plane, e.g., 10.0.0.1/8
    Tow host PCs, called Host-A and Host-B respectively, are connected to any 2 of the 4 ONetSwitch Zynq PL Ethernet ports, in a subnet for data plane, e.g., 192.168.0.1/24

  • Start the app from Host-Ctrl.

*** example ***
cd <dir-ofc-exec>/ryu3.23/ryu
ryu-manager --verbose ./app/msr-simple_switch/simple_switch_13.py
  • Power on the device to start the OpenFlow switch, then to connect to the controller.
    A message ending with 'connected' to the controller would show in the ONetSwitch serial console.

  • Try to ping between Host-A and Host-B, should get through.
    Either initialized by A or B, the ping triggers the bi-directional ICMP echo request and reply. The controller sends flow entries by self-learning on the input port.

####More..

  • Check the delay of ping

(1) is the first echo request/reply trip, which is processed by the controller software, with the delay of ~10ms.
(2) is a typical round trip processed by the software-impl OFS (vSwitch), with the delay of ~1ms.
(3) is a typical round trip processed by the hardware-impl OFS, with the delay of ~0.1ms.

*** OFS-SW example ***
user@computer-name:~$ ping -I eth1 192.168.0.100
PING 192.168.0.100 (192.168.0.100) from 192.168.0.1 eth1: 56(84) bytes of data.
64 bytes from 192.168.0.100: icmp_seq=1 ttl=64 time=9.89 ms  ---- (1)
64 bytes from 192.168.0.100: icmp_seq=2 ttl=64 time=1.42 ms  ---- (2)
64 bytes from 192.168.0.100: icmp_seq=3 ttl=64 time=1.40 ms
64 bytes from 192.168.0.100: icmp_seq=4 ttl=64 time=1.37 ms
64 bytes from 192.168.0.100: icmp_seq=5 ttl=64 time=1.38 ms
64 bytes from 192.168.0.100: icmp_seq=6 ttl=64 time=1.37 ms
...
*** OFS-HW example ***
user@computer-name:~$ ping -I eth1 192.168.0.100
PING 192.168.0.100 (192.168.0.100) from 192.168.0.1 eth1: 56(84) bytes of data.
64 bytes from 192.168.0.100: icmp_seq=1 ttl=64 time=11.797 ms ---- (1)
64 bytes from 192.168.0.100: icmp_seq=2 ttl=64 time=0.184 ms  ---- (3)
64 bytes from 192.168.0.100: icmp_seq=3 ttl=64 time=0.184 ms
64 bytes from 192.168.0.100: icmp_seq=4 ttl=64 time=0.184 ms
64 bytes from 192.168.0.100: icmp_seq=5 ttl=64 time=0.184 ms
64 bytes from 192.168.0.100: icmp_seq=6 ttl=64 time=0.166 ms
...
  • OFS-SW flow entries
    At the beginning, an entry with priority 0 for default pkt-in, sent to Table 0.
    During the self-learning on the input ports, two entries with priority 1, sent to Table 0.
    As a result, 3 active entries in Table 0. No more entry in other tables.
*** OFS-SW example ***
zynq> ./dpctl tcp:127.0.0.1:6632 stats-table
...
[{table="0", active="3", lookup="56", match="34",
{table="1", active="0", lookup="0", match="0",
...
{table="63", active="0", lookup="0", match="0"]
...
  • OFS-HW flow entries
    The default pkt-in entry sent to Table 0 is hacked by our modified version of CPqD. (You could see the entry is active in CPqD software if you try dpctl to show the status. However it does not effect in the hardware-impl flow table.)
    Instead, (as we can see in the init.sh for OFS-HW) use dpctl to add default entry for pkt-in to the first software-impl flow table.
    As a result, 3 active entries in Table 0, 1 active entry in the first software-impl table (for ONS30, it is Table 3, the fourth table.)
*** OFS-HW example ***  
(excuse the wrong counters for lookup and match caused by bug..)
zynq> ./dpctl tcp:127.0.0.1:6632 stats-table
...
[{table="0", active="3", lookup="3735928559", match="3735928559",
{table="1", active="0", lookup="3735928559", match="3735928559",
{table="2", active="0", lookup="3735928559", match="3735928559",
{table="3", active="1", lookup="30", match="17",
{table="4", active="0", lookup="0", match="0",
...
{table="63", active="0", lookup="0", match="0"]
...

###Run gui_topology.py

gui_topology.py runs web service to show the topology in GUI via browser.

Simple architecture of this app is shown below:
Ryu <- (Rest API) -> Web Server <- (WebSocket & REST) -> Web Browser

Notice that the GUI show needs to visit online java script 'http://d3js.org/d3.v3.min.js' , in index.html.
If you are not using a Host-Ctrl with multiple NICs, which can visit online resources during the demo, you have to download the .js then use it locally.
i.e. change the .js sourcing "src=http://d3js.org/d3.v3.min.js" in index.html , to something like "src=./d3.min.js".

####Steps to run

  • Setup the basic scenario.
    Better with more than 2 OpenFlow switches, since we need to observe the links between/among the devices.
    Notice that do NOT put any loop in the topo, since in this case the app cannot solve any Spanning Tree Protocol.

  • Optionally, join more physical/virtual switches, using mininet for example.

  • Start the app from Host-Ctrl.

*** example ***
cd <dir-ofc-exec>/ryu3.23/ryu
ryu-manager --verbose --observe-links ./app/gui_topology/gui_topology.py
### PYTHONPATH=. ../bin/ryu run --observe-links ./app/gui_topology/gui_topology.py
  • Power on all the devices to connect to the controller.
    A message ending with 'connected' to the controller would show in the ONetSwitch serial console.

  • Open your browser, access http://localhost:8080 or http://<ip address of ryu host>:8080 for the GUI topology.

  • Plug/Unplug the cable to check the change in GUI.

####More..

  • LLDP Link Observation
    Downstream, from Host-Ctrl to certain OFS Ethernet port, there is no entry dedicated for this pkt-out.
    Upstream, from some OFS Ethernet port to Host-Ctrl, one dedicated entry specifying following LLDP pattern for LLDP pkt-in is sent to Table 0, with the highest priority 65535.
    oxm{eth_dst="01:80:c2:00:00:0e", eth_type="0x88cc"}
    This is the ONLY entry in this case, for every Table 0 of the OFS.

  • Link Add and Delete
    Log from Host-Ctrl, when plugging/unplugging the Ethernet cable.

*** example ***
EVENT ofp_event->switches EventOFPPacketIn
EVENT ofp_event->switches EventOFPPacketIn
EVENT switches->WebSocketTopology EventLinkAdd
EVENT switches->WebSocketTopology EventLinkAdd

...

EVENT ofp_event->switches EventOFPPortStatus
EVENT ofp_event->dpset EventOFPPortStatus
EVENT switches->WebSocketTopology EventLinkDelete
EVENT switches->WebSocketTopology EventLinkDelete
⚠️ **GitHub.com Fallback** ⚠️