3. Manual Flow Installation with Open vSwitch

Open vSwitch is an open source implementation of a virtual multilayer switch. It provides network switch functionality for virtualized environments and commonly used in cloud computing platforms.

Due to its wide spread usage, Open vSwitch has also developed support for the OpenFlow protocol, making it a critical component of a Software Defined Network.

In this chapter, we will install flows manually using the Open vSwitch commands to understand its process.

Chapter Details
Chapter Goal Understand how flows are installed on Open vSwitch
Chapter Sections

3.1. Adding a Simple Flow

Our lab environment includes Open vSwitch as well as various management tools. For the purpose of installing flows, we will take a look at ovs-ofctl: A command line tool for monitoring and administering OpenFlow switches including, but not limited to, Open vSwitch.

Step 1 Log-in to your slab environment:

$ ssh sdn@<slab-IP>
# password: rocks
...
sdn@slab:~$

Step 2 Run the help command for ovs-ofctl:

sdn@slab:~$ ovs-ofctl --help
...
usage: ovs-ofctl [OPTIONS] COMMAND [ARG...]

For OpenFlow switches:
   show SWITCH                 show OpenFlow information
   dump-desc SWITCH            print switch description
   dump-tables SWITCH          print table stats
   mod-port SWITCH IFACE ACT   modify port behavior
   get-frags SWITCH            print fragment handling behavior
   set-frags SWITCH FRAG_MODE  set fragment handling behavior
   dump-ports SWITCH [PORT]    print port statistics
   dump-ports-desc SWITCH      print port descriptions
   dump-flows SWITCH           print all flow entries
   dump-flows SWITCH FLOW      print matching FLOWs
   dump-aggregate SWITCH       print aggregate flow statistics
...
sdn@slab:~$

As you can see, we will need a switch to manipulate flows on. Let’s use Mininet to spawn a set of switches and hosts.

Step 3 Start a simple topology on Mininet without any reference controllers:

sdn@slab:~$ sudo mn --topo single,3 --controller none --mac
...
mininet>

This command starts up a single switch with three hosts attached to it.

Step 4 Run a ping across the hosts to check connectivity:

mininet> h1 ping -c 3 h3
PING 10.0.0.3 (10.0.0.3) 56(84) bytes of data.
From 10.0.0.1 icmp_seq=1 Destination Host Unreachable
From 10.0.0.1 icmp_seq=2 Destination Host Unreachable
From 10.0.0.1 icmp_seq=3 Destination Host Unreachable
...
mininet>

Unlike the ping test we conducted in the previous chapter, the packet is simply dropped in this scenario because there is no network controller to interpret packet flow behavior. Let’s proceed by adding a simple flow using ovs-ofctl

Reference

For more information on ovs-ofctl command, visit http://openvswitch.org/support/dist-docs/ovs-ofctl.8.txt

Step 5 Add a flow on switch s1 with action=normal. An action of a flow indicates an action to take when a packet matches the flow entry. A normal action allows the device to conduct normal L2/L3 packet processing:

mininet> sh ovs-ofctl add-flow s1 action=normal
mininet>

Step 6 Verify the flow installation by executing the command ovs-ofctl dump-flows <bridge>. This command prints the OpenFlow table entries on a particular device:

mininet> sh ovs-ofctl dump-flows s1
NXST_FLOW reply (xid=0x4):
  cookie=0x0, duration=8.454s, table=0, n_packets=0, n_bytes=0, idle_age=8, actions=NORMAL
mininet>
Here are some of the fields to note:
  • duration - number of seconds the entry has been in the table
  • table - specific table in which the flow is installed on
  • n_packets - number of packets that have matched the entry
  • idle_age - number of seconds since last packet matched the entry

Step 7 Run a ping across the hosts to check connectivity:

mininet> h1 ping -c 3 h3
64 bytes from 10.0.0.3: icmp_seq=1 ttl=64 time=0.309 ms
64 bytes from 10.0.0.3: icmp_seq=2 ttl=64 time=0.034 ms
64 bytes from 10.0.0.3: icmp_seq=3 ttl=64 time=0.038 ms
...
mininet>

As a result of adding a flow entry on s1 the hosts now have connectivity.

Step 8 Take a look at the flows on s1 again:

mininet> sh ovs-ofctl dump-flows s1
NXST_FLOW reply (xid=0x4):
  cookie=0x0, duration=30.712s, table=0, n_packets=10,
  n_bytes=756, idle_age=10, actions=NORMAL
mininet>

Step 9 Delete the flow:

mininet> sh ovs-ofctl del-flows s1

Notes

The del-flows command will delete all existing flows on the indicated device. Take care not to delete flows unintentionally.

Checkpoint

  • What are the differences in the output of dump-flows command after pinging?
  • Verify that there are no flows installed on s1

3.2. Match Action Flows

The OpenFlow protocol allows a network controller to install specific match action rules on the switch. There are a large variety of rules that one can specify to define a flow. In this chapter, we will explore forwarding rules by specifying ports and by specifying MAC addresses of hosts.

Let’s take a look at the environment before proceeding.

Important

If you have previously exited from the mininet> prompt, start the environment again with the same settings from 3.1. Adding a Simple Flow section.

Step 1 Show the interfaces of s1:

mininet> sh ovs-ofctl show s1
...
1(s1-eth1): addr:d6:63:15:fc:e2:a8
   config:     0
   state:      0
   current:    10GB-FD COPPER
   speed: 10000 Mbps now, 0 Mbps max
2(s1-eth2): addr:06:71:25:e7:90:cd
   config:     0
   state:      0
   current:    10GB-FD COPPER
   speed: 10000 Mbps now, 0 Mbps max
3(s1-eth3): addr:0a:fe:43:27:29:48
   config:     0
   state:      0
   current:    10GB-FD COPPER
   speed: 10000 Mbps now, 0 Mbps max
LOCAL(s1): addr:46:cb:1e:d3:79:41
...
mininet>

Step 2 Note that the HWaddr (MAC) of each host should be in easy-to-read format:

mininet> h1 ifconfig | grep HWaddr
h1-eth0   Link encap:Ethernet  HWaddr 00:00:00:00:00:01
mininet> h2 ifconfig | grep HWaddr
h2-eth0   Link encap:Ethernet  HWaddr 00:00:00:00:00:02
mininet> h3 ifconfig | grep HWaddr
h3-eth0   Link encap:Ethernet  HWaddr 00:00:00:00:00:03

The following diagram summarizes our topology.

_images/ovs-match-action-diagram-3host.png

3.2.1. Port Forwarding Flow Entry

One way to provide connectivity to hosts is to simply direct all traffic input from one port to another port. In this scenario, we will direct incoming traffic from s1-eth1 to s1-eth3 and incoming traffic from s1-eth3 to s1-eth1. This bi-directional rule will allow us to test the connectivity using ICMP.

Step 1 Ensure that all nodes are available:

mininet> nodes
available nodes are:
h1 h2 h3 s1
mininet>

Step 2 Verify that there is no connectivity yet:

mininet> h1 ping -c 3 h3
PING 10.0.0.3 (10.0.0.3) 56(84) bytes of data.
From 10.0.0.1 icmp_seq=1 Destination Host Unreachable
From 10.0.0.1 icmp_seq=2 Destination Host Unreachable
From 10.0.0.1 icmp_seq=3 Destination Host Unreachable
...
mininet>

Step 3 Add a bi-directional entry for port match action rule:

mininet> sh ovs-ofctl add-flow s1 in_port=1,actions=output:3
mininet> sh ovs-ofctl add-flow s1 in_port=3,actions=output:1

Notice in our diagram that port number 1 corresponds to s1-eth1 and port number 3 corresponds to s1-eth3

Step 4 Try to ping between h1 and h3 again:

mininet> h1 ping -c 3 h3
64 bytes from 10.0.0.3: icmp_seq=1 ttl=64 time=0.323 ms
64 bytes from 10.0.0.3: icmp_seq=2 ttl=64 time=0.031 ms
64 bytes from 10.0.0.3: icmp_seq=3 ttl=64 time=0.035 ms
...
mininet>

You have successfully added a flow entry!

Checkpoint

Does h1 have connectivity with h2?

3.2.2. MAC Based Flow Entry

Let’s provide connection between h1 and h2 using MAC matching flow entries.

Step 1 Ensure that all nodes are available and that you are in the mininet> prompt:

mininet> nodes
h1 h2 h3 s1
mininet>

Step 2 Remove all existing flows on s1:

mininet> sh ovs-ofctl del-flows s1

Step 3 Add a bi-directional flow specifying the source and destination MAC addresses.

mininet> sh ovs-ofctl add-flow s1 dl_src=00:00:00:00:00:01,
                      dl_dst=00:00:00:00:00:02,actions=output:2
mininet> sh ovs-ofctl add-flow s1 dl_src=00:00:00:00:00:02,
                      dl_dst=00:00:00:00:00:01,actions=output:1

At this point, you may think it is sufficient to exchange ping between the hosts. However, this rule does not consider L2 broadcasting since the output action is unicast. You must add another flow allowing ARP requests.

Step 4 Add a flow to allow ARP requests:

mininet> sh ovs-ofctl add-flow s1 dl_type=0x806,nw_proto=1,actions=flood
  • dl_type - Specifies an Ethernet protocol type. 0x806 translates to ARP packets.
  • nw_proto - Specifies the network protocol. 1 indicates ICMP packets.
  • actions=flood - Specifies the flood action class which sends packets to all existing ports except the ingress port.

Step 5 Try to ping between h1 and h2:

mininet> h1 ping -c 3 h2
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.337 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.034 ms
64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=0.036 ms

Checkpoint

  • Why do you think a flow for ARP request had to be added for a ping test?
  • Do NOT cleanup Mininet. Proceed to the next section with the existing flows and topology.

3.2.3. Setting Match Priority

So far, we have added multiple types of flows using ovs-ofctl. In this segment, we will add a flow that has priority over the existing flow for a certain amount of time.

A priority has a value of 0 to 65535 and a default value of 32768. When two flow entries with wildcards are matched, the entry with the higher priority will match before the lower one.

Step 1 Let’s take a look at the existing flow rules:

mininet> sh ovs-ofctl dump-flows s1
   NXST_FLOW reply (xid=0x4):
   cookie=0x0, duration=1339.135s, table=0, n_packets=10, n_bytes=756, idle_age=35,
      dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02 actions=output:2
   cookie=0x0, duration=1331.507s, table=0, n_packets=11, n_bytes=798, idle_age=35,
      dl_src=00:00:00:00:00:02,dl_dst=00:00:00:00:00:01 actions=output:1
   cookie=0x0, duration=1312.294s, table=0, n_packets=1, n_bytes=42, idle_age=1309,
      arp,arp_op=1 actions=FLOOD

As you can see, we have a bi-directional rule that allows communication between packets from h1 to h2 and vice versa as defined by the MAC address.

Step 2 Check that h1 still has connectivity to h2:

mininet> h1 ping -c 3 h2
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.337 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.034 ms
64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=0.036 ms

Step 3 Add a rule on s1 to drop all connectivity:

mininet> sh ovs-ofctl add-flow s1 priority=40000,hard_timeout=30,actions=drop
mininet>
  • priority - Here, we set the priority to be greater than the default value (32768).
  • hard_timeout - Number of seconds the rule will persist before being deleted.
  • actions=drop - Any traffic coming through s1 will be dropped.

Based on this flow definition, we expect to see no connectivity between h1 and h2 for 30 seconds. After this hard timeout period, the flow will be deleted and connectivity will resume.

Step 4 Continually ping between h1 and h2:

mininet> h1 ping h2
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
# Host temporarily unreachable...
# Keep the ping running for more than 30 seconds
64 bytes from 10.0.0.2: icmp_seq=23 ttl=64 time=0.180 ms
64 bytes from 10.0.0.2: icmp_seq=24 ttl=64 time=0.034 ms
64 bytes from 10.0.0.2: icmp_seq=25 ttl=64 time=0.032 ms
# Press ctrl+C to exit ping and return to Mininet prompt
^C
mininet>

Success! As expected, the new flow rule prohibited network activity on s1 for the specified hard_timeout amount. Afterwards, the flow rule was dropped and the network re-established connectivity.

Checkpoint

What do you think will happen if you add a flow to drop packets on s1 with priority of 10000?

Step 5 Check the flows again and take a look at the n_packets:

mininet> sh ovs-ofctl dump-flows s1
NXST_FLOW reply (xid=0x4):
   cookie=0x0, duration=1892.267s, table=0, n_packets=19, n_bytes=1470, idle_age=532,
      dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02 actions=output:2
   cookie=0x0, duration=1884.639s, table=0, n_packets=16, n_bytes=1176, idle_age=532,
      dl_src=00:00:00:00:00:02,dl_dst=00:00:00:00:00:01 actions=output:1
   cookie=0x0, duration=1865.426s, table=0, n_packets=1, n_bytes=42, idle_age=1863,
      arp,arp_op=1 actions=FLOOD

You will notice that the packet counts for the first two flows have increased due to the ping. The packet count for flow rule that enables ARP remains at 1 because the host has cached the information in its local table.

Step 6 Exit Mininet and cleanup:

mininet> exit
sdn@slab:~$ sudo mn -c

Checkpoint

At this point, you should be familiar with operating Open vSwitch to manually edit flows!

Congratulations! You have completed 3. Manual Flow Installation with Open vSwitch