Experimenting with Software Defined Networks (SDN) on real hardware has become a lot easier since I discovered the Zodiac FX switch from Northbound Networks. This 4-port switch supports Openflow v1.0 and v1.3, and it supports many Openflow controllers.
This post describes the process of connecting the Zodiac FX switch with a Raspberry Pi, which runs an Openflow controller and SDN applications. This setup is intended for SDN-related research or training. But my goal here is to start the first step towards building a software defined home network.
I chose the Faucet controller for this implementation. This controller has been featured recently as a solution suitable for deployments in enterprise networks. This first phase of the implementation is a replication of the original post by Josh Bailey at https://faucet-sdn.blogspot.ca/2016/06/raucet-raspberry-pi-faucet-controlling.html.
Before we begin, I assume the reader has basic knowledge of the following:
- Software Defined Networking
- Linux OS (specifically Raspbian distro, which is based on Debian)
Hardware Components:
- Raspberry Pi 2 Model B (Rev 1.1)
- Zodiac FX Rev A (Firmware 0.68)
- Two or more devices for testing network connectivity
- Ethernet cables
Notes and assumptions:
If you want to replicate this implementation, you should note that I connect to the RP using Wi-Fi to free up the Ethernet port for switch connectivity, and I use Putty as a SSH client. It is also possible to connect to the RP directly using a keyboard and monitor. I use pico to edit various files; you can use any editor you prefer.
I also assume that you will install any missing software and tools that you need on the RP as you follow this post. The links will give you all the details you need.
Connectivity between RP and ZFX:
We begin by connecting the Raspberry Pi to the Zodiac FX switch. The RP will supply power to the ZFX via the USB cable included with the ZFX. Connect an Ethernet cable between the RP and port 4 on the ZFX. Plug the supplied USB cable into the ZFX and the RP. Then power up the RP. The switch should not have any other connections.
Log into the RP and edit the file “/etc/network/interfaces “to add or modify the IP address on the interface connecting to ZFX
sudo pico /etc/network/interfaces auto eth0 iface eth0 inet static address 10.0.1.8 netmask 255.255.255.0 gateway 10.0.1.99
Restart network services using the following command:
$ sudo /etc/init.d/networking restart
Verify connectivity to ZFX:
$ ping 10.0.1.99
The ZFX will appear in Debian as the serial device /dev/ttyACM.
$ dmesg | grep Zodiac [ 3.080257] usb 1-1.2: Product: Zodiac
Use Minicom to log into ZFX:
$ sudo apt-get install minicom $ minicom --device /dev/ttyACM0 Zodiac_FX# config Zodiac_FX(config)# show config ---------------------------------------------------------------- Configuration Name: Zodiac_FX MAC Address: 70:B3:D5:6C:D5:86 IP Address: 10.0.1.99 Netmask: 255.255.255.0 Gateway: 10.0.1.1 OpenFlow Controller: 10.0.1.8 OpenFlow Port: 6633 Openflow Status: Enabled Failstate: Secure Force OpenFlow version: Disabled Stacking Select: MASTER Stacking Select: Disabled --------------------------------------------------------------- Zodiac_FX(config)# exit Zodiac_FX#
Connecting to RYU Controller
The Ryu Controller is an open software-defined networking (SDN) Controller. For an introduction to Ryu and quick installation guide, visit this site and this. The following worked for my Raspberry Pi 2.
$ sudo apt-get update $ sudo apt-get install python-eventlet python-routes python-webob $ sudo apt-get install python-paramiko python-yaml libpython-dev $ sudo apt-get install tinyrpc ovs oslo.config msgpack-python $ sudo apt-get install --upgrade eventlet $ sudo pip install ipaddr $ sudo pip install --upgrade six $ git clone git://github.com/osrg/ryu.git $ cd ryu $ sudo python ./setup.py install
Verify that Ryu is installed properly:
$ ryu-manager --version ryu-manager 4.9
Once Ryu is installed, start the controller using the command:
$ ryu-manager --verbose ryu/ryu/app/simple_switch.py
You will see output like this:
loading app ryu/ryu/app/simple_switch.py loading app ryu.controller.ofp_handler instantiating app ryu/ryu/app/simple_switch.py of SimpleSwitch instantiating app ryu.controller.ofp_handler of OFPHandler BRICK SimpleSwitch CONSUMES EventOFPPortStatus CONSUMES EventOFPPacketIn BRICK ofp_event PROVIDES EventOFPPortStatus TO {'SimpleSwitch': set(['main'])} PROVIDES EventOFPPacketIn TO {'SimpleSwitch': set(['main'])} CONSUMES EventOFPEchoRequest CONSUMES EventOFPEchoReply CONSUMES EventOFPHello CONSUMES EventOFPPortDescStatsReply CONSUMES EventOFPPortStatus CONSUMES EventOFPSwitchFeatures CONSUMES EventOFPErrorMsg connected socket:<eventlet.greenio.base.GreenSocket object at 0x272ccb0> address:('10.0.1.99', 49236) hello ev <ryu.controller.ofp_event.EventOFPHello object at 0x2734290> move onto config mode switch features ev version=0x1,msg_type=0x6,msg_len=0xb0, xid=0xe755531bL,OFPSwitchFeatures(actions=1779,capabilities=7, datapath_id=123917682136454L,n_buffers=0,n_tables=1, ports={1:OFPPhyPort(port_no=1,hw_addr='cb:4e:3e:a4:00:30', name='eth0',config=0,state=0,curr=136,advertised=0, supported=0,peer=0), 2:OFPPhyPort(port_no=2, hw_addr='9d:ab:65:6d:8d:bf',name='eth1',config=0,state=0, curr=136,advertised=0,supported=0,peer=0), 3: OFPPhyPort(port_no=3, hw_addr='e4:b9:3f:35:4b:c9',name='eth2',config=0,state=1, curr=136,advertised=0,supported=0,peer=0)}) move onto main mode …
Connect two IP devices to ports 1 and 2 in the ZFX switch and configure their IP addresses to be on the same subnet. They should be able to ping each other.
Log into the ZFX using Mincom again and navigate to the Openflow context to check the status:
Zodiac_FX# openflow Zodiac_FX(openflow)# show status ---------------------------------------------------------------- Status: Connected Version: 1.0 (0x01) No tables: 1 No flows: 5 Total Lookups: 1561 Total Matches: 1162 ----------------------------------------------------------------
You can stop the controller by hitting CTRL-C or
$ sudo killall ryu-manager
Installing Faucet
Faucet is an Open Source Python-based Layer 2/3 switch controller for managing production networks. Faucet supports many traditional networking features, including: VLANs, ACLs, IPv6, Port Mirroring, Layer 3 routing, etc. An introduction to Faucet and quick installation guide can be found at https://github.com/REANNZ/faucet. More documentation can be found at https://github.com/REANNZ/faucet/tree/master/src/docs
This implementation is a replication of the original post by Josh Bailey at https://faucet-sdn.blogspot.ca/2016/06/raucet-raspberry-pi-faucet-controlling.html. Some details are changed or added.
Create a folder for the ZFX configuration files and create the yaml file shown below. Replace dp_id with the MAC Address of your ZFX:
$ mkdir /home/pi/zodiacfx $ sudo pico /home/pi/zodiacfx/zodiacfx.yaml version: 2 dps: zfx-switch-1: dp_id: 0x70B3D56CD586 interfaces: 1: native_vlan: 40 2: native_vlan: 40 3: native_vlan: 40 vlans: 40: name: "TEST_VLAN"
Supply the environment variables for the configuration and log files:
$ export FAUCET_CONFIG=~/zodiacfx/zodiacfx.yaml $ export FAUCET_LOG=~/zodiacfx/faucet.log $ export FAUCET_EXCEPTION_LOG=~/zodiacfx/faucet_exception.log
Start Faucet
$ ryu-manager ~/faucet/src/ryu_faucet/org/onfsdn/faucet/faucet.py –verbose
You should see output similar to the one produced by Ryu in the previous section (Faucet is an application of Ryu.)
At this point the two devices connected to ZFX should be able to ping each other and if you log into ZFX, the status of Openflow should look like this (notice the Openflow version is changed to v1.3).
Zodiac_FX# openflow Zodiac_FX(openflow)# show status ---------------------------------------------------------------- Status: Connected Version: 1.3 (0x04) No tables: 7 No flows: 57 Total Lookups: 21443 Total Matches: 21443 ----------------------------------------------------------------
Looking at the log files, you will see
$ more ~/zodiacfx/faucet.log Dec 17 15:45:11 faucet DEBUG DPID 123917682136454 (0x70b3d56cd586) connected Dec 17 15:45:11 faucet.valve INFO Configuring DPID 123917682136454 (0x70b3d56cd586) Dec 17 15:45:11 faucet.valve INFO Configuring VLAN vid:40 ports:1,2,3 Dec 17 15:45:11 faucet.valve INFO Port 1 added Dec 17 15:45:11 faucet.valve INFO Sending config for port 1 Dec 17 15:45:11 faucet.valve INFO Port 2 added Dec 17 15:45:11 faucet.valve INFO Sending config for port 2 Dec 17 15:45:11 faucet.valve INFO Port 3 added Dec 17 15:45:11 faucet.valve INFO Sending config for port 3 Dec 17 15:45:11 faucet.valve DEBUG Packet_in DPID 123917682136454 (0x70b3d56cd586) src:00:30:67:b1:d8:47 in_port:1 vid:40 Dec 17 15:45:11 faucet.valve INFO learned 1 hosts on vlan 40 Dec 17 15:45:12 faucet.valve DEBUG Packet_in DPID 123917682136454 (0x70b3d56cd586) src:d4:04:cd:9c:f0:e8 in_port:1 vid:40 …
At this point your ZFX will work as regular Layer 2 switch. I used mine to replace one of the switches at home. More about this later.