A Quick Introduction to Open vSwitch

In a previous article I discussed bridges and showed how the Linux utilities bridge-utils and iproute2 could be used to create virtual bridges within a system. This is great for simple set up but when deploying a cloud environment a bit more functionality is required and that’s where Open vSwitch comes in.

Open vSwitch is more than just a bridge it’s an entire multilayer switch designed to run massive automated networks. It supports a whole host of management interfaces and protocols and can also be managed programmatically though extensions. Fortunately my usage is quite modest and requires little more than knowing how to set up a few bridges and add ports to them.

In the example below I’m working on a virtual machine that has a single interface, eth0, defined.

First install Open vSwitch:

apt-get install openvswitch-switch

Then create a bridge which used to share eth0:

ovs-vsctl add-br br-eth0
ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:4a:5e:e1 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.141/24 brd 192.168.1.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fe4a:5ee1/64 scope link
       valid_lft forever preferred_lft forever
3: ovs-system: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default
    link/ether 5a:96:4d:c9:29:51 brd ff:ff:ff:ff:ff:ff
4: br-eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default
    link/ether be:2d:15:ec:cd:44 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::c406:adff:fee1:7b2e/64 scope link
       valid_lft forever preferred_lft forever

Notice that the bridge has now been created. There is also a new system interface called ovs-system this interface doesn’t do anything interesting (at least from the users point of view) and should be ignored. Now add the interface eth0 to the bridge br-eth0. Note, if you are working over SSH you will likely lose the connection at this point.

ovs-vsctl add-port br-eth0 eth0

The next step is to assign the IP address that was on eth0 to the bridge br-eth0:

ip addr del 192.168.1.141/24 dev eth0
ip addr add 192.168.1.141/24 dev br-eth0
ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master ovs-system state UP group default qlen 1000
    link/ether 08:00:27:4a:5e:e1 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::a00:27ff:fe4a:5ee1/64 scope link
       valid_lft forever preferred_lft forever
3: ovs-system: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default
    link/ether 5a:96:4d:c9:29:51 brd ff:ff:ff:ff:ff:ff
4: br-eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default
    link/ether 08:00:27:4a:5e:e1 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.141/24 scope global br-eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::c406:adff:fee1:7b2e/64 scope link
       valid_lft forever preferred_lft forever

Notice that eth0 now reports that ovs-system is it’s master. This is now Open vSwitch internally handles the mapping of interfaces to bridges. The bridge, however, now has the IP address that was on eth0 and so you should now be able to SSH back into the machine. At this point you can use an Open vSwitch utility to better understand the layout of the network:

ovs-vsctl show
3b252904-7acd-4c90-bd45-d282bb3f4294
    Bridge "br-eth0"
        Port "br-eth0"
            Interface "br-eth0"
                type: internal
        Port "eth0"
            Interface "eth0"
    ovs_version: "2.0.1"

The output of the show command clearly shows now port eth0 is now a slave of bridge br-eth0. The physical interface on a compute node generally need to accept packets for multiple IP addresses so promiscuous mode should be turned on:

ip link set br-eth0 promisc on
ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master ovs-system state UP mode DEFAULT group default qlen 1000
    link/ether 08:00:27:4a:5e:e1 brd ff:ff:ff:ff:ff:ff
3: ovs-system: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default
    link/ether 5a:96:4d:c9:29:51 brd ff:ff:ff:ff:ff:ff
4: br-eth0: <BROADCAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT group default
    link/ether 08:00:27:4a:5e:e1 brd ff:ff:ff:ff:ff:ff

Notice the new PROMISC state for the br-eth0 interface.

To remove eth0 from the bridge and then delete the bridge it’s as simple as:

ovs-vsctl del-port br-eth0 eth0
ovs-vsctl del-br br-eth0

Open vSwitch also supports vlans and to create an access (as opposed to a trunk) port simply add the tag argument to the add-port command like this:

ovs-vsctl add-port br-eth0 other_iface tag=7

This command added other_iface to the bridge as an access port for vlan number 7.