1 | |
---|
2 | |
---|
3 | OpenFlow on RPi |
---|
4 | Li Lin, Regina Hain |
---|
5 | |
---|
6 | The goal of this work is to run an OpenFlow controller on a raspberry pi. |
---|
7 | To do so, we used Open vSwitch to configure the virtual switches on the |
---|
8 | pi server and Ryu to run the controller and to inject custom flows. |
---|
9 | |
---|
10 | There are three major pieces of this project: |
---|
11 | 1. Use OVS to setup a useful and interesting network |
---|
12 | 2. Run a custom script with the Ryu controller to install flows and route packets |
---|
13 | 3. Demoing the system with a streaming webcam application |
---|
14 | |
---|
15 | ==Part I: Using OVS to set up a useful and interesting network== |
---|
16 | |
---|
17 | =Topology= |
---|
18 | _______________________________________________________________________ |
---|
19 | |Pi Server | |
---|
20 | | ____________ _______________ _______________ | |
---|
21 | | | BR1 | | BR2 | | BR3 | | |
---|
22 | | | 10.10.1.1 | PP* | 10.10.2.1 | PP* | 10.10.3.1 | | |
---|
23 | | | 2|-------|2 3|-------|2 | | |
---|
24 | | |_____1______| |______1________| |______1________| | |
---|
25 | | _____|______ ______|________ ______|________ | |
---|
26 | | |eth1 | |eth2 | |eth3 | | |
---|
27 | | |10.10.1.x | |10.10.2.x | |10.10.3.x | | |
---|
28 | | |____________| |_______________| |_______________| | |
---|
29 | | | | | | |
---|
30 | | | | | | |
---|
31 | |________|_____________________|_______________________|________________| |
---|
32 | | | | |
---|
33 | _____|______ ______|________ ______|________ |
---|
34 | | Pi1 | | Pi2 | | Pi3 | |
---|
35 | | 10.10.1.2 | | 10.10.2.2 | | 10.10.3.2 | |
---|
36 | |____________| |_______________| |_______________| |
---|
37 | |
---|
38 | |
---|
39 | *: PP means patch port |
---|
40 | |
---|
41 | =Description= |
---|
42 | This setup consists of 4 pi's- one acting as a server 3 as the clients. |
---|
43 | There are 3 accompanying interfaces on the server- eth1, eth2, eth3, each |
---|
44 | their own subnet. Additionally, each is connected to a separate OVS bridge. |
---|
45 | The OVS bridges forward packets to all other bridges via patch ports. |
---|
46 | |
---|
47 | =Setup on server= |
---|
48 | To configure this network, run configure_pt1 |
---|
49 | |
---|
50 | =Setup on client= |
---|
51 | To configure the ip address of client pi's, add the following |
---|
52 | lines to /etc/dhcpcd.conf depending on its ip address and router values |
---|
53 | |
---|
54 | # In pi1 /etc/dhcpcd.conf |
---|
55 | interface eth0 |
---|
56 | static ip_address=10.10.1.2/24 |
---|
57 | static router=10.10.1.1 |
---|
58 | |
---|
59 | # In pi2 /etc/dhcpcd.conf |
---|
60 | interface eth0 |
---|
61 | static ip_address=10.10.2.2/24 |
---|
62 | static router=10.10.2.1 |
---|
63 | |
---|
64 | # In pi3 /etc/dhcpcd.conf |
---|
65 | interface eth0 |
---|
66 | static ip_address=10.10.3.2/24 |
---|
67 | static router=10.10.3.1 |
---|
68 | |
---|
69 | =Test= |
---|
70 | To test, run ping from one client Pi to another client Pi. Connectivity |
---|
71 | should be present, via the OVS bridge and patch port topology, between |
---|
72 | all three client Pi's. |
---|
73 | |
---|
74 | =Teardown= |
---|
75 | To teardown this network, run teardown_pt1 |
---|
76 | |
---|
77 | |
---|
78 | ==Part II: Using Ryu to install flows and route packets over our OVS network== |
---|
79 | |
---|
80 | =Topology= |
---|
81 | _______________________________________________________________________ |
---|
82 | |Pi Server | |
---|
83 | | ____________________________________________________________ | |
---|
84 | | | BR1 | | |
---|
85 | | | 10.10.1.10 | | |
---|
86 | | | | | |
---|
87 | | |_____1_____________________3_______________________2________| | |
---|
88 | | _____|______ ______|________ ______|________ | |
---|
89 | | |eth1 | |eth2 | |eth3 | | |
---|
90 | | |10.10.1.1 | |10.10.1.3 | |10.10.1.2 | | |
---|
91 | | |____________| |_______________| |_______________| | |
---|
92 | | | | | | |
---|
93 | | | | | | |
---|
94 | |________|_____________________|_______________________|________________| |
---|
95 | | | | |
---|
96 | _____|______ ______|________ ______|________ |
---|
97 | | Pi1 | | Pi2 | | Pi3 | |
---|
98 | | 10.10.1.4 | | 10.10.1.5 | | 10.10.1.6 | |
---|
99 | |____________| |_______________| |_______________| |
---|
100 | |
---|
101 | Note that this topology is different from that in part I. This is because |
---|
102 | having 3 bridges added too much unneeded complexity when crafting custom |
---|
103 | flows. This time we used 1 bridge to connect all three interfaces and |
---|
104 | connecting them up through separate ports. |
---|
105 | |
---|
106 | =RYU Script Description= |
---|
107 | |
---|
108 | This script creates a custom flow that matches on any packet coming in |
---|
109 | on port 1 (source 10.10.1.4) and out on port 3 (destination 10.10.1.5). |
---|
110 | It forwards that packet as usual, but also |
---|
111 | creates a duplicate packet, modifies its destination (to the address |
---|
112 | of pi3) and sends to port 2 (pi 3). The result is that pi3 gets a copy |
---|
113 | of every packet that is sent from pi1 to pi2. |
---|
114 | |
---|
115 | Note that to turn on the special flow, *insert_special_flow* must be set to |
---|
116 | True in ryu_13_custom.py |
---|
117 | |
---|
118 | To see that the custom flow is installed correctly (note that installation |
---|
119 | will occur only on the first instance of a packet with source 10.10.1.4 |
---|
120 | and destination 10.10.1.5 captured by our controller), on the server type |
---|
121 | $ sudo ovs-ofctl dump-flows br1 |
---|
122 | |
---|
123 | =Setup= |
---|
124 | To configure this network, run configure_pt2 |
---|
125 | Note that step 5, connecting the controller to the bridge, takes the |
---|
126 | ip address of the server's eth0 interface. This can change based on |
---|
127 | network and pi. To find the correct ip address to use, in a terminal type |
---|
128 | $ ifconfig -a |
---|
129 | |
---|
130 | =Run= |
---|
131 | To run the ryu controller with our custom script type: |
---|
132 | $ ryu-manager ./path/to/ryu_13_custom.py |
---|
133 | To ensure controller connectivity type: |
---|
134 | $ sudo ovs-vsctl show |
---|
135 | and you should see something like this (if connected): |
---|
136 | Bridge "br1" |
---|
137 | Controller "tcp:128.89.68.110:6633" |
---|
138 | is_connected: true |
---|
139 | |
---|
140 | =Testing= |
---|
141 | |
---|
142 | Ping test |
---|
143 | On 10.10.1.4 (pi1) type |
---|
144 | $ ping 10.10.1.5 |
---|
145 | You will see that 2 different hosts will reply to the pings- both |
---|
146 | pi2 (10.10.1.5) and pi3 (10.10.1.6). |
---|
147 | |
---|
148 | Netcat test |
---|
149 | On 10.10.1.5 (pi2) type |
---|
150 | $ nc -l 1234 |
---|
151 | On 10.10.1.6 (pi3) type |
---|
152 | $ nc -l 1234 |
---|
153 | On 10.10.1.4 (pi1) type |
---|
154 | $ echo "HELLO WORLD" | nc 10.10.1.5 1234 -u |
---|
155 | |
---|
156 | You should see that HELLO WORLD should be printed on both pi2 and pi3. |
---|
157 | This only works in udp mode (-u) and the reason is left as an |
---|
158 | exercise for the reader. |
---|
159 | |
---|
160 | =Teardown= |
---|
161 | To teardown this network, run teardown_pt2 |
---|
162 | |
---|
163 | |
---|
164 | ==Part III: Demoing via a streaming webcam application== |
---|
165 | |
---|
166 | In this demo, pi1 (10.10.1.4) will send raw video bytes captured from |
---|
167 | its webcam to pi2 (10.10.1.5) via the netcat application. Pi2 will capture |
---|
168 | the udp packets by using netcat to listen on a specified port and save |
---|
169 | the data to a pipe file. Pi2 will then run mplayer on the file to output the |
---|
170 | video to screen. Pi3 will perform the same exact functions as Pi2, and |
---|
171 | since the controller sends a duplicate copy of every udp packet to Pi3, |
---|
172 | it can receive and render the webcam video also. |
---|
173 | |
---|
174 | On Pi1: |
---|
175 | 1. Compile the C file used to read data from the webcam |
---|
176 | $ gcc capturevideo.c -o capturevideo |
---|
177 | 2. Execute and pipe the output to 10.10.1.5 via netcat |
---|
178 | $ ./capturevideo -c 1000 -o | nc 10.10.1.5 5000 |
---|
179 | *. Instructions and code taken from: https://www.raspberrypi.org/forums/viewtopic.php?t=98778&p=685576 |
---|
180 | |
---|
181 | On Pi2: |
---|
182 | 1. If not installed already, install mplayer |
---|
183 | $ sudo apt-get install mplayer |
---|
184 | 2. Create a pipe file |
---|
185 | $ mkfifo video.fifo |
---|
186 | 3. Call netcat and listen to specified port |
---|
187 | $ nc.traditional -lu -p 5000 > video.fifo |
---|
188 | 4. Use mplayer to open video |
---|
189 | $ mplayer video.fifo -demuxer rawvideo -rawvideo w=640:h=480:format=yuy2 |
---|
190 | |
---|
191 | On Pi3: |
---|
192 | 1. If not installed already, install mplayer |
---|
193 | $ sudo apt-get install mplayer |
---|
194 | 2. Create a pipe file |
---|
195 | $ mkfifo video.fifo |
---|
196 | 3. Call tcpdump to listen to specified port |
---|
197 | $ sudo tcpdump -i eth0 udp port 5000 -w video.fifo |
---|
198 | Note: Netcat will not accept packets because it requires a connection, |
---|
199 | even when solely listening for udp packets, when the datagram size is over |
---|
200 | 1500 bytes. |
---|
201 | 4. Use mplayer to open video |
---|
202 | $ mplayer video.fifo -demuxer rawvideo -rawvideo w=640:h=480:format=yuy2 |
---|
203 | |
---|
204 | |
---|