The OpenFlow 1.3 software switch is built upon the Stanford OpenFlow 1.0 reference switch and Ericsson's Traffic Lab OpenFlow 1.1 switch and is intended for fast experimentation purposes.
The following components are available in the release:
The switch makes use of the NetBee library to parse packets, so we need to install it first.
sudo apt-get install cmake libpcap-dev libxerces-c-dev libpcre3-dev flex bison pkg-config autoconf libtool libboost-dev
cd ~/Downloads
unzip nbeesrc-*
bison --version
wget -nc http://mirror.cs.nchu.edu.tw/debian/pool/main/b/bison/bison_2.5.dfsg-2.1_amd64.deb
wget -nc http://mirror.cs.nchu.edu.tw/debian/pool/main/b/bison/libbison-dev_2.5.dfsg-2.1_amd64.deb
sudo dpkg -i bison_2.5.dfsg-2.1_amd64.deb libbison-dev_2.5.dfsg-2.1_amd64.deb
cd nbeesrc-*/src
cmake .
make
echo $?
0
sudo cp ../bin/libn*.so /usr/local/lib
sudo ldconfig
sudo cp -R ../include/* /usr/local/include/
cd ../..
git clone https://github.com/CPqD/ofsoftswitch13.git
cd ofsoftswitch13
./boot.sh
./configure
make
echo $?
0
sudo make install
dpctl --version
dpctl 1.3.0 compiled Apr 1 2015 14:29:07
ofdatapath --help
ofdatapath: userspace OpenFlow datapath usage: ofdatapath [OPTIONS] LISTEN... where LISTEN is a passive OpenFlow connection method on which to listen for incoming connections from the secure channel. Passive OpenFlow connection methods: ptcp:[PORT] listen to TCP PORT (default: 6633) punix:FILE listen on Unix domain socket FILE Configuration options: -i, --interfaces=NETDEV[,NETDEV]... add specified initial switch ports -L, --local-port=NETDEV set network device for local port --no-local-port disable local port -d, --datapath-id=ID Use ID as the OpenFlow switch ID (ID must consist of 12 hex digits) -m, --multiconn enable multiple connections to the same controller. --no-slicing disable slicing Other options: -D, --detach run in background as daemon -P, --pidfile[=FILE] create pidfile (default: /usr/local/var/run/ofdatapath.pid) -f, --force with -P, start even if already running -v, --verbose=MODULE[:FACILITY[:LEVEL]] set logging levels -v, --verbose set maximum verbosity level -h, --help display this help message -V, --version display version information
sudo ofdatapath -D --pidfile=/usr/local/var/run/s1.pid ptcp:6633
cat /usr/local/var/run/s1.pid
8522
sudo kill -2 `cat /usr/local/var/run/s1.pid`
ofprotocol tcp:<switch-host>:<switch-port> tcp:<ctrl-host>:<ctrl-port>
ofprotocol --help
ofprotocol: secure channel, a relay for OpenFlow messages. usage: ofprotocol [OPTIONS] DATAPATH [CONTROLLER] DATAPATH is an active connection method to a local datapath. CONTROLLER is an active OpenFlow connection method; if it is omitted, then secchan performs controller discovery. Active OpenFlow connection methods: tcp:HOST[:PORT] PORT (default: 6633) on remote TCP HOST unix:FILE Unix domain socket named FILE fd:N File descriptor N Passive OpenFlow connection methods: ptcp:[PORT] listen to TCP PORT (default: 6633) punix:FILE listen on Unix domain socket FILE Controller discovery options: --accept-vconn=REGEX accept matching discovered controllers --no-resolv-conf do not update /etc/resolv.conf Networking options: --inactivity-probe=SECS time between inactivity probes --max-idle=SECS max idle for flows set up by secchan --max-backoff=SECS max time between controller connection attempts (default: 15 seconds) -l, --listen=METHOD allow management connections on METHOD (a passive OpenFlow connection method) -m, --monitor=METHOD copy traffic to/from kernel to METHOD (a passive OpenFlow connection method) --out-of-band controller connection is out-of-band --stp enable 802.1D Spanning Tree Protocol --no-stp disable 802.1D Spanning Tree Protocol Rate-limiting of "packet-in" messages to the controller: --rate-limit[=PACKETS] max rate, in packets/s (default: 1000) --burst-limit=BURST limit on packet credit for idle time Daemon options: -D, --detach run in background as daemon -P, --pidfile[=FILE] create pidfile (default: /usr/local/var/run/ofprotocol.pid) -f, --force with -P, start even if already running Logging options: -v, --verbose=MODULE[:FACILITY[:LEVEL]] set logging levels -v, --verbose set maximum verbosity level --log-file[=FILE] enable logging to specified FILE (default: /usr/local/var/log/openflow/ofprotocol.log) Other options: -h, --help display this help message -V, --version display version information --check-leaks=FILE log malloc and free calls to FILE
Dpctl is a management utility that enable some control over the OpenFlow switch. With this tool it's possible to add flows to the flow table, query for switch features and status, and change other configurations.
dpctl [OPTIONS] SWITCH COMMAND [ARG...]
dpctl --help
dpctl: OpenFlow switch management utility usage: dpctl [OPTIONS] SWITCH COMMAND [ARG...] SWITCH ping [N] [B] latency of B-byte echos N times SWITCH monitor monitors packets from the switch SWITCH features show basic information SWITCH get-config get switch configuration SWITCH port-desc print port description and status SWITCH meter-config [METER] get meter configuration SWITCH stats-desc print switch description SWITCH stats-flow [ARG [MATCH]] print flow stats SWITCH stats-aggr [ARG [MATCH]] print flow aggregate stats SWITCH stats-table print table stats SWITCH stats-port [PORT] print port statistics SWITCH stats-queue [PORT [QUEUE]] print queue statistics SWITCH stats-group [GROUP] print group statistics SWITCH stats-meter [METER] print meter statistics SWITCH stats-group-desc [GROUP] print group desc statistics SWITCH set-config ARG set switch configuration SWITCH flow-mod ARG [MATCH [INST...]] send flow_mod message SWITCH group-mod ARG [BUCARG ACT...] send group_mod message SWITCH meter-mod ARG [BANDARG ...] send meter_mod message SWITCH port-mod ARG send port_mod message SWITCH table-mod ARG send table_mod message SWITCH queue-get-config PORT send queue_get_config message OpenFlow extensions SWITCH set-desc DESC sets the DP description SWITCH queue-mod PORT QUEUE BW adds/modifies queue SWITCH queue-del PORT QUEUE deletes queue Active OpenFlow connection methods: tcp:HOST[:PORT] PORT (default: 6633) on remote TCP HOST unix:FILE Unix domain socket named FILE fd:N File descriptor N Logging options: -v, --verbose=MODULE[:FACILITY[:LEVEL]] set logging levels -v, --verbose set maximum verbosity level --log-file[=FILE] enable logging to specified FILE (default: /usr/local/var/log/openflow/dpctl.log) Other options: --strict use strict match for flow commands -t, --timeout=SECS give up after SECS seconds -h, --help display this help message -V, --version display version information
dpctl tcp:127.0.0.1 features
SENDING: feat_req RECEIVED: feat_repl{dpid="0x0000f2a580810a1e", buffs="256", tabs="64", aux_id="0", caps="0x4f"]}
sudo mkdir /src3/mininet; sudo chown jssu:jssu /src3/mininet
cd /src3/mininet
git clone git://github.com/mininet/mininet
mininet/util/install.sh -n3fxw
mn --version
2.2.1d2
sudo mn --topo single,2 --mac --switch user --controller remote
sudo dpctl unix:/tmp/s1 stats-flow table=0
SENDING: stat_req{type="flow", flags="0x0", table="0", oport="any", ogrp="any", cookie=0x0", mask=0x0", match=oxm{all match}} RECEIVED: stat_repl{type="flow", flags="0x0", stats=[]}
sudo dpctl unix:/tmp/s1 flow-mod table=0,cmd=add in_port=1 apply:output=2
sudo dpctl unix:/tmp/s1 flow-mod table=0,cmd=add in_port=2 apply:output=1
sudo dpctl unix:/tmp/s1 stats-flow table=0
SENDING: stat_req{type="flow", flags="0x0", table="0", oport="any", ogrp="any", cookie=0x0", mask=0x0", match=oxm{all match}} RECEIVED: stat_repl{type="flow", flags="0x0", stats=[ {table="0", match="oxm{in_port="1"}", dur_s="7", dur_ns="727000", prio="32768", idle_to="0", hard_to="0", cookie="0x0", pkt_cnt="0", byte_cnt="0", insts=[apply{acts=[out{port="2"}]}]}, {table="0", match="oxm{in_port="2"}", dur_s="2", dur_ns="937000", prio="32768", idle_to="0", hard_to="0", cookie="0x0", pkt_cnt="0", byte_cnt="0", insts=[apply{acts=[out{port="1"}]}]}]}
h1 ping h2
Let's start a simple topology with KVM by using Tap device
Host1: 192.168.180.200, host2: 192.168.180.201
sudo ofdatapath -D --pidfile=/usr/local/var/run/s1.pid -i eth0,tap0,tap1 punix:/usr/local/var/run/s1.sock
Apr 13 19:06:01|00001|dp_ports|ERR|tap0 device has assigned IPv6 address fe80::5824:18ff:fec1:bb3a RTNETLINK answers: No such file or directory Apr 13 19:06:01|00002|dp_ports|ERR|tap1 device has assigned IPv6 address fe80::9011:2fff:fe9a:3e03 RTNETLINK answers: No such file or directory
Command, port-desc, sends a message requesting the ports description, with the current configurations.
sudo dpctl unix:/usr/local/var/run/s1.sock port-desc
SENDING: stat_req{type="port-desc", flags="0x0"} RECEIVED: stat_repl{type="port-desc", flags="0x0" {no="1", hw_addr="50:e5:49:42:f5:40", name="eth0", config="0x0", state="0x4", curr="0x2020", adv="0xe83f", supp="0x283f", peer="0x0", curr_spd="1048576kbps", max_spd="1048576kbps"}, {no="2", hw_addr="de:24:01:f4:ad:d3", name="tap0", config="0x0", state="0x4", curr="0x802", adv="0x0", supp="0x0", peer="0x0", curr_spd="10240kbps", max_spd="0kbps"}, {no="3", hw_addr="be:7c:7d:e2:74:1b", name="tap1", config="0x0", state="0x4", curr="0x802", adv="0x0", supp="0x0", peer="0x0", curr_spd="10240kbps", max_spd="0kbps"}, {no="local", hw_addr="12:1f:88:b8:94:4d", name="tap:", config="0x0", state="0x4", curr="0x802", adv="0x0", supp="0x0", peer="0x0", curr_spd="10240kbps", max_spd="0kbps"}}}
Show all flows present in table 0.
sudo dpctl unix:/usr/local/var/run/s1.sock stats-flow table=0
SENDING: stat_req{type="flow", flags="0x0", table="0", oport="any", ogrp="any", cookie=0x0", mask=0x0", match=oxm{all match}} RECEIVED: stat_repl{type="flow", flags="0x0", stats=[]}
Ping between the topology hosts
sudo dpctl unix:/usr/local/var/run/s1.sock flow-mod table=0,cmd=add in_port=2 apply:output=3
sudo dpctl unix:/usr/local/var/run/s1.sock flow-mod table=0,cmd=add in_port=3 apply:output=2
sudo dpctl unix:/usr/local/var/run/s1.sock stats-flow table=0
SENDING: stat_req{type="flow", flags="0x0", table="0", oport="any", ogrp="any", cookie=0x0", mask=0x0", match=oxm{all match}} RECEIVED: stat_repl{type="flow", flags="0x0", stats=[ {table="0", match="oxm{in_port="2"}", dur_s="108", dur_ns="61000", prio="32768", idle_to="0", hard_to="0", cookie="0x0", pkt_cnt="29", byte_cnt="2282", insts=[apply{acts=[out{port="3"}]}]}, {table="0", match="oxm{in_port="3"}", dur_s="100", dur_ns="505000", prio="32768", idle_to="0", hard_to="0", cookie="0x0", pkt_cnt="21", byte_cnt="1946", insts=[apply{acts=[out{port="2"}]}]}]}
ping 192.168.180.254
Forward packets to gateway
sudo dpctl unix:/usr/local/var/run/s1.sock flow-mod table=0,cmd=add in_port=1 apply:output=2
sudo dpctl unix:/usr/local/var/run/s1.sock flow-mod table=0,cmd=add in_port=2 apply:output=1
sudo route add default gw 192.168.180.254
ping 8.8.8.8
VM startup script
cat start-CPqD0-AsDaemon
#! /bin/bash MEM=512M MACaddr='52:54:00:b8:9c:58' # Don't Edit, File automatically generated by Config-Kvm-vhoston script if [ $EUID -ne 0 ] then sudo echo "Super User passwd, please:" if [ $? -ne 0 ] then echo "Sorry, need su privilege!" exit 1 fi fi sudo chmod 666 /dev/net/tun sudo tunctl -u jssu -t tap0 #sudo ifconfig tap0 192.168.180.3 netmask 255.255.255.255 up #sudo sysctl net.ipv4.conf.tap0.proxy_arp=1 #sudo route add -host 192.168.180.200 dev tap0 /src3/KVM/bin/vhostOn.sh mkdir /src3/KVM/network-CPqD0 echo "Starting VM: CPqD0..., mem=${MEM}" screen -S CPqD0 -d -m qemu-system-x86_64 -name CPqD0 -localtime -curses \ -m ${MEM} -enable-kvm \ -monitor unix:/src3/KVM/network-CPqD0/MonSock,server,nowait \ -netdev tap,id=hostnet0,ifname=tap0,vhost=on \ -net nic,vlan=0,netdev=hostnet0,macaddr=${MACaddr},model=virtio \ -drive index=0,media=disk,if=virtio,file=/src3/KVM/img/CPqD0.ovl
VM stop and restore lan script
cat stop-CPqD0-restore-lan
#! /bin/bash # Don't Edit, File automatically generated by Config-Kvm-vhoston script if [ $EUID -ne 0 ] then sudo echo "Super User passwd, please:" if [ $? -ne 0 ] then echo "Sorry, need su privilege!" exit 1 fi fi if [ -S /src3/KVM/network-CPqD0/MonSock ]; then echo "system_powerdown" | socat - unix-connect:/src3/KVM/network-CPqD0/MonSock echo "Please wait 5 seconds." sleep 5 else echo "Socket has been removed! Shutdown by ssh or resotre Lan only." fi ping -c 3 192.168.180.200 if [ $? -eq 0 ]; then echo "CPqD0 still alive, shut it down. Enter passwd twice!" ssh -t jssu@192.168.180.200 'sudo init 0' else rm -rf /src3/KVM/network-CPqD0 fi echo "Restore lan..." if [ -d /proc/sys/net/ipv4/conf/tap0 ]; then sudo /sbin/ifconfig tap0 down sudo tunctl -d tap0 fi