Open vSwitch: Introduction – Part 2

This part covers:

  • Main Components (ovsdb-server, ovs-vswitchd, ovs kernel module)
  • Utilities (ovs-vsctl, ovs-ofctl, ovs-appctl, etc)
  • Modes (normal & flow)

Part 1 is here.

Open vSwitch Components

The following diagram shows Open vSwitch main components and in which space (kernel, user or remote server) each component is located

Let’s describe each one of them in more detail.


One of the core components. It is a Daemon which controls all Open vSwitch switches on the system.

When started for the first time, it gets its initial configuration from the ovsdb-server, using the OVSDB management protocol.

It communicates with the kernel module using the netlink protocol. For communication with the system, it uses netdev abstract interface.

It is also responsible for implementing switch features such as mirroring, bonding and VLANs.


A lightweight database that holds switch level configuration. Thanks to ovsdb-server, the switch configuration changes are persistent and should survive a system reboot. It Communicates with ovs-vswitchd using the OVSDB management protocol.

OpenvSwitch Kernel Module

Handles the switching and tunneling.

When a packet arrives, it checks if there is an existing entry for it (meaning if it’s an familiar flow) if not, the packet sent to the userspace, where it processed by ovs-vswitchd.

It’s designed to be fast and simple and knows nothing of OpenFlow. OpenFlow communication is done exclusively with ovs-vswitchd.

It implements “datapaths”.   Datapath is a collection of physical or virtual ports. You can think of it as a bridge, but in the kernel and not in userspace. Each datapath can have one or more ports, which called “vports”. Datapaths are controlled with the ‘ovs-dpctl’ command (we’ll cover it in the ‘utilities’ section).

OpenFlow controller

Although it’s not part of Open vSwitch components, it’s important to know what it is for since, you might have it in your environment.

All the flows kept in ovs-vswitchd will be lost in case of a restart or a crash. So to keep important flows persistent, an OpenFlow controller is usually used.

It’s common to find it installed on a remote server (that’s why it placed in different “space” in the drawing) although it can be installed on the same server.

Open vSwitch Utilities


Querying and updating the configuration of ovs-vswitchd.

Let’s see a few examples (most of them we already used in the previous post)

> ovs-vsctl add-br 'my_bridge' # Adds a new bridge named 'my_bridge'

> ovs-vsctl add-port my_bridge new_port # Adds a new port named 'new_port' in 'my_bridge'
> ovs-vsctl show # Prints summary of of all the bridges, ports and interfaces

    Bridge my_bridge
        Port "eth0"
            Interface "eth0"
        Port my_bridge
            Interface my_bridge
                type: internal
    ovs_version: "2.5.0"
> ovs-vsctl del-br my_bridge # Delete the bridge 'my_bridge'

> sudo ovs-vsctl list-ifaces my_bridge # List the interfaces of 'my_bridge'



Querying and controlling OpenFlow switches and controllers.

A few examples (more details on OpenFlow and ovs-ofctl can be found in the OpenFlow post):

> ovs-ofctl show <bridge_name> # Prints information on the bridge, its ports and flow table

OFPT_FEATURES_REPLY (xid=0x2): dpid:0000ce8b5ba7a84f
n_tables:254, n_buffers:256
actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst
 1(eth0): addr:52:54:00:9f:63:08
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
 LOCAL(my_bridge): addr:ce:8b:5b:a7:a8:4f
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0
> ovs-ofctl dump-flows my_bridge # Prints all the flows in 'my_bridge' flow table

NXST_FLOW reply (xid=0x4):
 cookie=0x0, duration=176807.518s, table=0, n_packets=110496, n_bytes=5904834, idle_age=0, hard_age=65534, priority=0 actions=NORMAL
> ovs-ofctl add-flow my_Bridge action=normal # Add a new flow


Configuring the switch kernel module. Allows to to modify, create and delete data-paths.

> ovs-dpctl add-dp my_dp # Add a new data path

> ovs-dpctl add-if my_dp eth0 # Adds existing interface to the specified data path
> ovs-dpctl show # Prints summary of the data paths and theirs ports

	lookups: hit:116813 missed:8250 lost:0
	flows: 4
	masks: hit:145936 total:3 hit/pkt:1.17
	port 0: ovs-system (internal)
	port 1: my_bridge (internal)
	port 2: eth0


Sends commands to running Open vSwitch daemon.

One of its common uses is ‘ovs-appctl fsb/show <bridge_name>’. It basically prints the MAC address table.

> sudo ovs-appctl fdb/show my_bridge

 port   VLAN       MAC           Age
LOCAL     0  ce:8b:5b:a7:a8:4f    0
    1     0  52:54:00:7b:f9:ea    0


Creating and managing the public-key infrastructure for OpenFlow switches.

> ovs-pki init # Creates an initial PKI structure

> ovs-pki req+sign ctl controller # Creates controller private key and a certificate


A simple OpenFlow controller that may be useful for testing (don’t use it for production).

> vs-testcontroller ptcp:  # Creates an test controller that waits for incoming connections

Open vSwitch Modes

Open vSwitch bridge can operate in either normal mode or flow mode when forwarding packets.

Normal mode

In normal mode, it acts as a layer 2 learning switch:

  1. When a frame first received it compares the frame’s source MAC address to the one in the table.
    • If the source is unknown (= it’s not in the MAC address table) then it adds the source MAC address to the table with the port number the packet was received on
  2. It compares the destination MAC (where this packet should reach at the end) to the one in the MAC address table
    • If there is an entry, the switch forwards the frame out through the associated port
    • If there is no entry, it floods the packet out from all its ports, except the port where the frame was received

To view the MAC address table, you can use ‘ovs-appctl fdb/show’

> ovs-appctl fdb/show <bridge_name>

port    VLAN      MAC            Age
LOCAL     0  ce:8b:5b:a7:a8:4f    0
    1     0  52:54:00:7b:f9:ea    0

Flow mode

In flow mode, things are a little bit more complex. The switch makes forwarding decisions based on OpenFlow table entries.

A switch might have one or more flow tables. A flow table can be created manually by adding flows with ‘ovs-ofctl add-flow’ command or it can be set by an OpenFlow controller (as seen in the components drawing).

I won’t go into much detail on OpenFlow, there is a dedicated post for that, but let’s describe the workflow of a packet reaching a switch which operates in flow mode:

  1. When a packet first arrives the switch, it processed first by the lowest number flow table (usually table 0).  Each table consists of flows or more accurately, flow entries.
  2. Each flow entry contains several fields/components. The packet is then matched to the ‘match fields’.
    • ‘match fields’ are basically packet headers, the ingress port and optional additional fields such as the metadata. Match fields can be for example a destination IP address, VLAN id, UDP source port, ICMP code, etc.
    • In case the packet matches several flow entries, the entry with the highest priority (anther field in flow entry) will be chosen.
  3. Once a match made, the action part (which also specified in the entry) defines what to do next. The action can be: forward to a specific port, drop, process through the specified group –  those are called “required actions” (since the switch is required to support them). There are also optional actions such as: change TTL, change header fields, push tag.
    • If the packet didn’t match any ‘field match’, this situation called ‘table-miss’ and unless there is a controller where the packet information can be sent to, the packet is dropped or redirected to another table.

5 thoughts on “Open vSwitch: Introduction – Part 2

  1. I am trying to create your first example, a bridge with a bond ports enp5s0 enp6s0.
    Configuring the ifcfg files is not bad, but I can’t get bond0 to start.


  2. Hi folks,

    I need some help with the following scenario:

    There is a Centos 7 Host running QEMU/KVM, 3 physical network interfaces available;
    – a Netgear GS108PEv3 switch
    – an Ubiquiti Unifi AP AC Pro

    On the host, the following virtual machines are running:
    – 1 VM is a pfSense router, handling WAN, firewall rules, DHCP and VLANs, LAN=
    – 1 VM is a Linux based PBX server, VLAN tag=80,
    – 1 VM is a Windows based Blue Iris server, VLAN tag=50,

    One of the host’s NIC should be the pfSense’s WAN.
    A second physical NIC of the host is the LAN, linking the virtual machines to the real world through the Netgear switch then the Unifi AP.

    I’m trying to use OpenVSwitch here.

    I should be able to communicate from LAN to VLANs and in certains conditions (pfSense firewall) – between VLANs.

    I can ping, from LAN to VLANs and across VLANs.
    But, if I’m trying to open, let’s say, the PBX admin page (VLAN80) from LAN or any other VLAN except VLAN80
    or to have remote desktop access to Blue Iris server (VLAN50) from any other network except VLAN50,
    both will fail.

    An image make 1000 words, I’ve uploaded one here:

    Also, when the 2nd NIC is linked to OpenVSwitch, I’ll loose the SSH access to the host… for that reason my host have a 3rd NIC, a wireless adapter drived by Hostapd. I’d like to have this one removed and to SSH the host from LAN network

    I just discovered OpenVSwitch and I’ve tried to adapt some scenarios to mine’s.
    But it looks that I’m missing something, could someone help?…


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s