| 10 | |
| 11 | = Openflow Tutorial = |
| 12 | To get started ensure that you have flukes up and running on your system. If do not know how to install |
| 13 | flukes please take a look at this page: [https://geni-orca.renci.org/trac/wiki/flukes Flukes]. [[BR]] |
| 14 | |
| 15 | For this tutorial you will need an image with OVS pre-installed in it. Don't panic, RENCI |
| 16 | provides you an image that has OVS installed in it. To use that, all you need to do is, open the |
| 17 | '''“.flukes.properties”''' file in your home directory and add the following lines at the bottom of it. [[BR]] |
| 18 | |
| 19 | |
| 20 | image'''XX'''.name=OVS_image [[BR]] |
| 21 | image'''XX'''.url=http://geni-images.renci.org/images/standard/debian/deb6-ovs-neuca-v1.0.0.xml [[BR]] |
| 22 | image'''XX'''.hash=0f897559d6379b2a726bce6a96b7f569a5dc11e6 [[BR]] |
| 23 | |
| 24 | '''Note:''' Ensure that you replace XX with the sequence number so that images are mentioned in an order.[[BR]] |
| 25 | |
| 26 | Now, to check if flukes is able to read the image option, open flukes and create a node by left clicking |
| 27 | in the request view pane. After creating the node, right click and select edit properties. You should be |
| 28 | able to find an option in the images section with the name “OVS_image”.[[BR]] |
| 29 | |
| 30 | [[Image(Figure1_openflow.png)]] [[BR]] |
| 31 | |
| 32 | |
| 33 | '''Figure (1)''' |
| 34 | |
| 35 | With that you have successfully completed the first step. In the next step, you need to run an Openflow |
| 36 | controller and ensure that it is reachable via Internet. You can run any Openflow controller that is |
| 37 | available, but we will be using floodlight controller for this tutorial.[[BR]] |
| 38 | |
| 39 | You can download floodlight by clicking on this link [http://floodlight.openflowhub.org/download/ Floodlight]. [[BR]] |
| 40 | Download the jar file as well as the floodlightdefault.properties file. [[BR]] |
| 41 | |
| 42 | In the properties file, delete the line '''“net.floodlightcontroller.forwarding.Forwarding,\“''' and save the |
| 43 | file. Now, open a new terminal on the box where you are planning to run the controller and type the |
| 44 | following line.[[BR]] |
| 45 | |
| 46 | “java -jar <floodlight jar file name including “.jar”> -cf <path to the modified properties file>"[[BR]] |
| 47 | |
| 48 | If you find the output on your console similar to the ones in the screen shot below then you are done |
| 49 | with setting up the controller.[[BR]] |
| 50 | |
| 51 | [[Image(Figure2_openflow.png)]][[BR]] |
| 52 | |
| 53 | ''' Figure(2)''' |
| 54 | |
| 55 | |
| 56 | Final missing piece is “Avior”, a GUI based tool which is used to manipulate flow entries in the |
| 57 | switches via user friendly interface rather than rest API. Click on the link below to download the jar file |
| 58 | and start running the tool.[[BR]] |
| 59 | |
| 60 | |
| 61 | [http://openflow.marist.edu/gettingstarted.html OpenFlow : Getting Started][[BR]] |
| 62 | |
| 63 | For smooth operation, run this tool on the same box where the controller is running. When you type |
| 64 | “java -jar <path to the Avior jar file>” you should be getting a prompt similar to the one show below.[[BR]] |
| 65 | |
| 66 | Enter “0.0.0.0” as the IP [ assuming the controller is running on the same box. If not, then enter the IP |
| 67 | on which controller is reachable] and click on launch button. [[BR]] |
| 68 | |
| 69 | [[Image(Figure3_openflow.png)]][[BR]] |
| 70 | |
| 71 | '''Figure(3)''' |
| 72 | |
| 73 | '''NOTE: Ensure that the controller is running and is reachable from this box.''' [[BR]] |
| 74 | |
| 75 | After clicking on the launch button, a new GUI appears on the screen similar to the one shown below. [[BR]] |
| 76 | |
| 77 | [[Image(Figure4_openflow.png)]][[BR]] |
| 78 | |
| 79 | '''Figure(4)''' |
| 80 | |
| 81 | Now you are all set for your first Openflow experiment on ExoGeni. [[BR]] |
| 82 | |
| 83 | === Life of an ICMP packet in an Openflow network: === |
| 84 | |
| 85 | First, we are going to create a simple six node topology with four nodes acting as switches and rest of |
| 86 | them as hosts. [[BR]] |
| 87 | |
| 88 | [[Image(Figure5_openflow.png)]][[BR]] |
| 89 | '''Figure (5)''' |
| 90 | |
| 91 | Here, nodes 0 and 5 are the hosts and rest of them are switches. [[BR]] |
| 92 | |
| 93 | Now we need to configure each node before we submit the request for resource allocation. This can be |
| 94 | done by editing the properties of each node [right click and select edit properties].[[BR]] |
| 95 | |
| 96 | Configure each switch [nodes 1,2,3,4] using the screen shots below as a reference. Configure IP |
| 97 | addresses on each node in such a way that you can tell which node is on the other side of the link by looking |
| 98 | at the IP. For example: link 3 connects nodes 2 and 0, hence IP address on node 2 is configured as |
| 99 | 192.168.1.20 to indicate that node 0 is on the other end of the link. Also, select ovs_image as the image |
| 100 | to be used.[[BR]] |
| 101 | Lastly, in the post boot script, copy and paste the commands shown below:[[BR]] |
| 102 | [[BR]] |
| 103 | |
| 104 | {{{ |
| 105 | #!/bin/bash |
| 106 | ovs-vsctl add-br test |
| 107 | ovs-vsctl add-port test eth1 |
| 108 | ovs-vsctl add-port test eth2 |
| 109 | ovs-vsctl add-port test eth3 |
| 110 | ovs-vsctl set-controller test tcp:<controller ip address>:6633 |
| 111 | ovs-vsctl set-fail-mode test secure |
| 112 | }}} |
| 113 | |
| 114 | |
| 115 | The above commands are used to create a data path or a switch [named as test] and add interfaces to it.[[BR]] |
| 116 | |
| 117 | The last command configures the controller's IP and port number details using the set-controller command.[[BR]] |
| 118 | |
| 119 | '''Note: Do not forget to add the controller's IP address in the set-controller command.''' |
| 120 | |
| 121 | [[Image(Figure6_openflow.png)]][[BR]] |
| 122 | ''' Figure (6)'''[[BR]] |
| 123 | |
| 124 | The above steps have to be repeated on the remaining three switches.[[BR]] |
| 125 | |
| 126 | After we finish configuring switches, we need to configure the hosts. Except for the step where we add |
| 127 | the OVS commands to the post boot script all the other steps described above are to be followed. To |
| 128 | distinguish the hosts from switches, configure the interfaces with IP address from a different sub-net, |
| 129 | say 192.168.2.0/24.[[BR]] |
| 130 | |
| 131 | Once you are done configuring the nodes, go ahead and submit the slice by giving it a name. You can |
| 132 | check the status of your request in the manifest view by specifying the name of the slice in the text box |
| 133 | and clicking on the “Query for manifest” button.[[BR]] |
| 134 | |
| 135 | When you notice status of all the nodes as active, switch to the controller's terminal and you should be |
| 136 | able to see logs similar to the ones in the below screen shot.[[BR]] |
| 137 | |
| 138 | [[Image(Figure7_openflow.png)]][[BR]] |
| 139 | '''Figure(7)'''[[BR]] |
| 140 | |
| 141 | |
| 142 | Now, switch over to the Avior’s control panel. You should be able to see four switches listed along with |
| 143 | their DPIDs'.[[BR]] |
| 144 | |
| 145 | [[Image(Figure8_openflow.png)]][[BR]] |
| 146 | '''Figure(8)'''[[BR]] |
| 147 | |
| 148 | Since we cannot modify DPIDs to a more readable format, we need to manually map the nodes to their |
| 149 | DPIDs. To do that, we need to login into each switch/node and type the below command.[[BR]] |
| 150 | |
| 151 | |
| 152 | “ovs-ofctl show test”[[BR]] |
| 153 | |
| 154 | |
| 155 | [[Image(Figure9_openflow.png)]][[BR]] |
| 156 | |
| 157 | '''Figure(9)'''[[BR]] |
| 158 | |
| 159 | As you can see in the above screen shot, DPID is displayed in the first line of the output. Carefully map |
| 160 | each node/switch to its DPID so that you can follow rest of the rest of tutorial with out any issues. Below |
| 161 | is the mapping used while wetting this tutorial.[[BR]] |
| 162 | |
| 163 | [[Image(Figure10_openflow.png)]][[BR]] |
| 164 | '''Figure(10)'''[[BR]] |
| 165 | |
| 166 | To make our life easier we are going to configure static ARP entries on both the hosts. If you plan to |
| 167 | move forward without configuring static ARP entries then you need to install flow rules specific to |
| 168 | ARP packets, which will double the work. [FYI: we have disabled learning switch on the controller as |
| 169 | well as in OVS]. You can configure static ARP entries using the command '''“arp -s <ip> <mac>”'''. For |
| 170 | example: "arp -s 192.168.2.6 fe:16:3e:00:57:b3 -i eth1” is used to specify that host with IP address |
| 171 | “192.168.2.6” and MAC address “fe:16:3e:00:57:b3” can be reached via interface eth1. [[BR]] |
| 172 | |
| 173 | Similarly, configure the static ARP entry on the other host (node 5). [[BR]] |
| 174 | |
| 175 | In this experiment, we are going to route the ICMP request packets from the node0 via “node1 → |
| 176 | node3 → node5” path and ICMP replies from node5 along the path “node3 → node4 → node2 → |
| 177 | node1 → node0”. To do that, we need to know the Openflow port numbers of interfaces on each |
| 178 | switch. [[BR]] |
| 179 | |
| 180 | One way to find out is to use the command “ovs-ofctl show test” on each switch (refer to figure[9]) and |
| 181 | make a note of them. [[BR]] |
| 182 | |
| 183 | To configure a flow, switch to Avior's control panel [do not panic if it gets struck while you are in |
| 184 | middle of something. Restart it and start over from the beginning] and click on the drop down arrow |
| 185 | beside tools. You will be able to find “flow manager” option. Switch to the flow manager window and select the switch [using the mapping created] to inset a flow entry and then click on new flow. [[BR]] |
| 186 | |
| 187 | [[Image(Figure11_openflow.png)]][[BR]] |
| 188 | |
| 189 | '''Figure(11)'''[[BR]] |
| 190 | |
| 191 | As you can see in the screen shot below, you will be asked to configure four fields. First, enter a name |
| 192 | for the flow, say “ICMP request flow_<dest ip>”. Next, click on actions and select output from the drop |
| 193 | down box and enter the port number [look into mapping between the interfaces and ports] you want the |
| 194 | packet to exit the switch from and click on save.[[BR]] |
| 195 | |
| 196 | [[Image(Figure12_openflow.png)]][[BR]] |
| 197 | |
| 198 | '''Figure (12)'''[[BR]] |
| 199 | |
| 200 | [[Image(Figure13_openflow.png)]][[BR]] |
| 201 | '''Figure (13)'''[[BR]] |
| 202 | |
| 203 | |
| 204 | Now, click on match option and enter appropriate values for different fields as show in Figure [13]. [[BR]] |
| 205 | '''Ensure that you enter the right input port value and also data layer type.'''[[BR]] |
| 206 | |
| 207 | Lastly, save the match information and click on push. You should get a status message indicating |
| 208 | that your flow was pushed successfully.[[BR]] |
| 209 | |
| 210 | [[Image(Figure14_openflow.png)]][[BR]] |
| 211 | '''Figure(14)'''[[BR]] |
| 212 | |
| 213 | Carefully follow the same procedure and insert flows accordingly in all the switches. The procedure is |
| 214 | same for both ICMP requests as well as ICMP replies. All you need to do is type in the right input port and |
| 215 | output port values and the destination IP. [[BR]] |
| 216 | |
| 217 | After you have configured all the four switches, nodes 1 & 3 should end up with two flow entries and |
| 218 | the other two switches [2 & 4] with one entry each. Verify your flow entries with the entries shown in |
| 219 | the below screen shots. [[BR]] |
| 220 | |
| 221 | [[Image(Figure15_openflow.png)]][[BR]] |
| 222 | '''Figure(15): node1 flow entries'''[[BR]] |
| 223 | |
| 224 | [[Image(Figure16_openflow.png)]][[BR]] |
| 225 | '''Figure(16): node3 flow entries'''[[BR]] |
| 226 | |
| 227 | [[Image(Figure17_openflow.png)]][[BR]] |
| 228 | '''Figure(17): node4 flow entries'''[[BR]] |
| 229 | |
| 230 | [[Image(Figure18_openflow.png)]][[BR]] |
| 231 | '''Figure(18): node2 flow entries'''[[BR]] |
| 232 | |
| 233 | After verifying all the flow entries, start sending ping packets from node0 to node5. Ensure that ping |
| 234 | packets originate from the right interface i.e. the source IP should be 192.168.2.2. One way to do that |
| 235 | is using the -I option of ping command. For example: if interface eth1 is configured with IP |
| 236 | “192.168.2.2” then we need to use the command “ping 192.168.2.6 -I eth1” for the ping to pass.[[BR]] |
| 237 | |
| 238 | In case you don't see any ping replies then you can debug the packet path using packet counters, which |
| 239 | indicate whether packets were hitting the TCAM entry [see the “packets column of the flow entry in the |
| 240 | above screen shot”]. If the counter doesn't increment then cross check the flow entry on that switch as |
| 241 | well as the flow entries on other switches to ensure that packets are being forwarded on the right path. |
| 242 | You can also use “tcpdump” tool to monitor packets on an interface. Moreover, OVS provides a |
| 243 | way to monitor packets being forwarded by a switch using “ovs-vsctl snoop <bridge name>” |
| 244 | command. [replace bridge name with test for this experiment]. [[BR]] |
| 245 | |
| 246 | Now, that we have successfully completed the ping test. Lets try to break it. There are many ways to do |
| 247 | it. One can delete one of the flow entries or remove the static ARP entries on one of the hosts. Lets do |
| 248 | the later one by removing the ARP entry on node5 using the command “arp -d 192.168.2.2”. Now, the |
| 249 | packet counters increase along the flow path “node1 → node3 → node5” and remain constant along the |
| 250 | flow path “node5 → node3 → node4 → node2 → node1 → node0”. [[BR]] |
| 251 | |
| 252 | |
| 253 | [[Image(Figure19a_openflow.png)]][[BR]] |
| 254 | |
| 255 | [[Image(Figure19b_openflow.png)]][[BR]] |
| 256 | '''Figure(19): Flow entries on node 1'''[[BR]] |
| 257 | |
| 258 | I hope you found the tutorial useful. Keep experimenting with different topologies and configurations.[[BR]] |