These instructions were written with the help of TJ OConnor. For variations of WRT1x00ac series routers, see the OpenWRT page and tweak build and configuration settings appropriately.

TODO:

  • Recommend flashing stock OpenWRT first
  • Explain “dual firmware”
  • Check if “tc - 4.0.0-1 - Traffic control utility” is needed during compile. Notes that openflow would not start without it.
  • Check if various kernel options are needed, as listed in these instructions

Step 1: Build Custom OpenWRT Firmware

The OpenWRT wiki has up-to-date Build Instructions. The following is based on these instructions and include adding the CPqD package for OpenFlow v1.3.

Download build environment and dependencies.

sudo apt-get update
sudo apt-get install git-core build-essential libssl-dev libncurses5-dev unzip gawk zlib1g-dev
sudo apt-get install subversion mercurial # optional

Clone OpenWRT repository (and choose a release).

mkdir ~/wrtof
cd ~/wrtof
git clone -b chaos_calmer git://github.com/openwrt/openwrt.git

Update feeds.

cd ~/wrtof/openwrt
./scripts/feeds update -a
./scripts/feeds install -a

Integrate CPqD package for OpenFlow v1.3.

cd ~/wrtof
git clone https://github.com/CPqD/openflow-openwrt.git
cd ~/wrtof/openwrt/package
ln -s ~/wrtof/openflow-openwrt/openflow-1.3/
cd ~/wrtof/openwrt
ln -s ~/wrtof/openflow-openwrt/openflow-1.3/files

Configure the build.

cd ~/wrtof/openwrt
make menuconfig

Select Target System (Marvell Armada 37x/38x/XP)
Select Target Profile (Linksys WRT1900ACS (Shelby)) # for the WRT1900ACS V1 or V2

Under network
Select <M> hostapd
Select <*> hostapd-common
Select <*> hostapd-common-old
Select <M> hostapd-mini
Select <*> hostapd-utils

Select <*> openflow

TODO: Some instructions suggest some other configure options. Are they needed?

Build it (this will take while).

make

Note, if you get a build error and when you re-make with make -j1 V=s you see errors related to rsa-sign.o, check out this issue. I ran into this when building OpenWrt with Debian Stretch. You can either downgrade OpenSSL, or patch the OpenWrt code.

[~/wrtof/openwrt]% find . -name rsa-sign.c
./build_dir/host/u-boot-2014.10/lib/rsa/rsa-sign.c
./build_dir/host/u-boot-2014.10/tools/lib/rsa/rsa-sign.c
[~/wrtof/openwrt]% cd build_dir/host/u-boot-2014.10 
[~/wrtof/openwrt/build_dir/host/u-boot-2014.10]% patch -p1 < ~/wrtof/openssl-fix.patch
patching file lib/rsa/rsa-sign.c
[~/wrtof/openwrt/build_dir/host/u-boot-2014.10]% cd ~/wrt/openwrt
[~/wrtof/openwrt]% make

Copy the firmware for safe keeping.

mkdir ~/wrtof/firmware
cp ~/wrtof/openwrt/bin/mvebu/openwrt-mvebu-* ~/wrt/firmware

Step 2: Flash the firmware

The above process produced two image files:

[~/wrtof/firmware]% ls openwrt-*
openwrt-mvebu-armada-385-linksys-shelby-squashfs-factory.img
openwrt-mvebu-armada-385-linksys-shelby-squashfs-sysupgrade.tar

If you are installing directly from the OEM Linksys Firmware, then use the -factory.img version. This can be flashed by navigating the OEM Linksys Web interface: Connectivity -> Manual Update.

If you already have OpenWRT on your router, then you will use the -sysupgrade.tar. Copy the file to the router and flash it. Be sure to clear the settings (-n) when installing this as a new firmware. Alternatively, you can use the OpenWRT Web interface, remembering to untick “Keep Settings.”

[~/wrtof/firmware]% scp openwrt-mvebu-armada-385-linksys-shelby-squashfs-sysupgrade.tar root@router.ip:
[~/wrtof/firmware]% ssh root@router.ip
root@OpenWrt:~# sysupgrade -n openwrt-mvebu-armada-385-linksys-shelby-squashfs-sysupgrade.tar

Step 3: Initial Setup and WAN Interface Access

The next step will assume a connection from the WAN interface. This step enables SSH on the WAN interface and sets a root password. Note: If you can setup up a static DHCP configuration for the WAN interface, it will make your life easier. Bonus points if you use DNSMasq to assign a DNS hostname.

Connect an ethernet cable to a LAN port and receive a DHCP lease.

[~/wrtof/firmware]% telnet 192.168.1.1
root@OpenWrt:~# passwd
New password:
Retype password:
Password for root changed by root

Option A: Allow just SSH

root@OpenWrt:~# vi /etc/config/firewall
...
config rule
    option src wan
    option dest_port 22
    option target ACCEPT
    option proto tcp

Option B: Allow everything to connect to WAN (more flexible if you are on your own LAN).

root@OpenWrt:~# vi /etc/config/firewall
... for the "wan" zone
-   option input REJECT
+   option input ACCEPT

Finally, restart the firewall:

root@OpenWrt:~# /etc/init.d/firewall restart

Step 4: Network Configuration

The following network configuration will enable OpenFlow on all of the LAN and WLAN interfaces. Furthermore, the configuration separates each LAN switch port into a different VLAN so that it is uniquely identifiable from the OpenFlow controller. Since the configuration modifies the LAN interface, it is best to make this configuration from a connection to the WAN interface.

Note: This configuration is based on instructions from KickStartSDN, but interface and port information needs to be customized for your router based on the OpenWRT page for your router. Note that the WRT1900ACS interface and port configuration is different than the WRT1900AC, so be careful. Look at the diagrams and adjust accordingly. It may also be useful to review the OpenWRT Switch Documentation.

root@OpenWrt:~# ssh root@router.wan.interface.ip

/etc/config/network

config interface 'loopback'
        option ifname 'lo'
        option proto 'static'
        option ipaddr '127.0.0.1'
        option netmask '255.0.0.0'

config globals 'globals'
        option ula_prefix 'fd7b:cf33:5065::/48'

config interface 'wan'       
        option ifname 'eth0' 
        option proto 'dhcp'   
                              
config interface 'wan6'       
        option ifname 'eth0'  
        option proto 'dhcpv6' 

config interface 'lan'
        option ifname 'eth1.1'
        option type 'bridge' 
        option proto 'static'
        option ipaddr '192.168.1.1'
        option netmask '255.255.255.0'
                                      
config interface 'lan2'               
        option ifname 'eth1.2'
        option proto 'static'
                              
config interface 'lan3'       
        option ifname 'eth1.3'
        option proto 'static' 
                              
config interface 'lan4'     
        option ifname 'eth1.4'
        option proto 'static'
                              
config switch                 
        option name 'eth0'    
        option reset '1'      
        option enable_vlan '1'
                            
config switch_vlan          
        option device 'eth1'
        option vlan '1'     
        option ports '0 6t' 
                            
config switch_vlan          
        option device 'eth1'
        option vlan '2'     
        option ports '1 6t' 
                            
config switch_vlan          
        option device 'eth1'
        option vlan '3'     
        option ports '2 6t' 
                            
config switch_vlan          
        option device 'eth1'
        option vlan '4'    
        option ports '3 6t'

/etc/config/wireless

config wifi-device 'radio0'
        option type 'mac80211'
        option channel '36'
        option hwmode '11a'
        option path 'soc/soc:pcie-controller/pci0000:00/0000:00:01.0/0000:01:00.0'
        option htmode 'VHT80'
        #option disabled '1'
        option country 'US'

config wifi-iface
        option device 'radio0'
        option network 'lan'
        option mode 'ap'
        option ssid 'OpenWrt'   
        option encryption 'psk2'
        option key 'supersecret'
                           
config wifi-device 'radio1'   
        option type 'mac80211'
        option channel '11'
        option hwmode '11g'                                                       
        option path 'soc/soc:pcie-controller/pci0000:00/0000:00:02.0/0000:02:00.0'
        option htmode 'HT20'
        #option disabled '1'
        option country 'US'
                 
config wifi-iface             
        option device 'radio1'
        option network 'lan'
        option mode 'ap'     
        option ssid 'OpenWrt'   
        option encryption 'psk2'
        option key 'supersecret'

Finally, restart the network (here is where it is good to be connected via the WAN interface).

root@OpenWrt:/etc/config# /etc/init.d/network restart

Step 4: Setting up OpenFlow

Notes:

  • Need to change /etc/functions.sh to /lib/functions.sh in both /sbin/ofup and /sbin/ofdown (could this have been done during build?

/etc/config/openflow

config 'ofswitch'
        option 'dp' 'dp0'
        option 'dpid' '000000000001'
        option 'ofports' 'eth1.1 eth1.2 eth1.3 eth1.4 wlan0 wlan1'
        option 'ofctl' 'tcp:127.0.0.1:6633'
        option 'mode'  'outofband'

Install python and pox

opkg update
opkg install python unzip wget
wget https://github.com/noxrepo/pox/archive/carp.zip
unzip carp.zip

Put this very simple controller code in pox-carp/pox/forwarding/hubacls.py

from pox.core import core
import pox.openflow.libopenflow_01 as of

log = core.getLogger()

def _handle_PacketIn (event):
    packet = event.parsed
    ip=packet.find('ipv4')
    if (ip):
	'[!] '+str(ip.srcip)+'->'+str(ip.dstip)
    msg = of.ofp_packet_out(data = event.ofp)
    msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD))
    event.connection.send(msg)
def launch (disable_flood = False):
    core.openflow.addListenerByName("PacketIn", _handle_PacketIn)
    log.info("[+] Hubacls-NG Running.")

Start the controller, which will print connections to the network.

root@OpenWrt:~# cd pox-carp/
root@OpenWrt:~/pox-carp# python pox.py forwarding.hubacls log.level --DEBUG

Old

You’ll find this post in your _posts directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to run jekyll serve, which launches a web server and auto-regenerates your site when a file is updated.

To add new posts, simply add a file in the _posts directory that follows the convention YYYY-MM-DD-name-of-post.ext and includes the necessary front matter. Take a look at the source for this post to get an idea about how it works.

Jekyll also offers powerful support for code snippets:

def print_hi(name)
  puts "Hi, #{name}"
end
print_hi('Tom')
#=> prints 'Hi, Tom' to STDOUT.

Check out the Jekyll docs for more info on how to get the most out of Jekyll. File all bugs/feature requests at Jekyll’s GitHub repo. If you have questions, you can ask them on Jekyll Talk.