OpenVSwitch Programming (II)
There are more ways for interacting with OVS that through the OpenFlow interface. In fact, the OVS interface can be accessed in three different ways. Look at the following graph from the OVS docs:
_
| +-------------------+
| | ovs-vswitchd |<-->ovsdb-server
| +-------------------+
| | ofproto |<-->OpenFlow controllers
| +--------+-+--------+ _
| | netdev | |ofproto-| |
userspace | +--------+ | dpif | |
| | netdev | +--------+ |
| |provider| | dpif | |
| +---||---+ +--------+ |
| || | dpif | | implementation of
| || |provider| | ofproto provider
|_ || +---||---+ |
|| || |
_ +---||-----+---||---+ |
| | |datapath| |
kernel | | +--------+ _|
| | |
|_ +--------||---------+
||
physical
NICNetlink-layer interface
The netlink layer is the lowest API that can be used for programming OpenVSwitch. This was the best API a couple of years ago. It is also as bit of a pain as you have to deal with messages serialization and deserialization, but it is probably the best way of programming OVS in performance terms.
In this model, and using a reactive programming model, you can create a pool with multiple netlinks to the kernel and use it for installing new flows and for reading packets from OVS. For any new packet that does not match the current set of rules in the datapath (the flows table), you will get a flow match (ie, a set of flow keys, something like *Port(0), Priority(0), Eth(Src=AB:CD:EF:12:34:56, Dst=AC:DE:FE:12:34:56), EtherType=0x800, IP(Src=”192.168.0.3”, Dst=”192.168.0.4”)...* and the packet that triggered it. Then you must process the packet and determine what to do with it, and insert a new rule in OVS with this exact flow match and an action for that match.
There are two advantages in using this method. First, netlink-level programming gives you access to stuff not available at other levels, so you can access all the low-level matches and actions provided by the OVS module, not necessarily exposed at upper layers (for example, OVS 2.x allows matches on specific TCP flags, but I think this is not exposed through the OpenFlow interface). Second, packets that go up to user space are directly forwarded to our controller program, so many copies and CPU cycles are saved.
The second point has been minimized in OVS 2.x thanks to the wildcard matches. This makes a big difference in performance terms, as we can set general rules for matching packets and reduce the number of packets going up to the controller (ie, you can specify *Port(0), Priority(0), Eth(Src=AB:CD:EF:12:34:56, Dst=AC:DE:FE:12:34:56), EtherType=0x800, IP(Src=”192.168.0.3”, Dst=”*”)...” ACTION=”forward(Port(2))*)
I’ve been working at this level but I‘m not sure if I would recommend it for new developments. The big advantage of using this interface is that new packets (in the reactive programming model) go directly to you (ie, they do not go through a OpenFlow controller, too many copies, etc), but OVS 2.x and wildcard matches reduce considerably the number of packets flowing to user space, so I don’t know if this make sense anymore...
Using the DPIF interface
The DPIF interface is a good approach to the problem, as it provides complete access to all the features of the OpenVSwitch module. I would definitely use this API for new developments when using languages like C/C++. The interface is specified in this and this files. The interface is very intuitive and easy to use. It would also allow to use different datapath providers, like DPDK.
OpenFlow interface
The OpenFlow interface has been useless until the latest versions of OpenVSwitch. I don’t know if big companies have been really using it, maybe Nicira. OpenFlow is probably not mature enough as a useful standard for all scenarios, and I think you could not get good throughput unless you use a proactive programming model... I’m not an OpenFlow expert so I cannot make a strong statement here though…
However programming the datapath at this level has two big advantages:
- portability: using OpenFlow means you can talk to other switches, or you could use this OVS vSwitch for talking to a DPDK datapath.
- remote access: you can access the OpenFlow interface remotely, for example from a central server or from border gateways in your network (ie, used for load balancing). If you want to do this with the other access models, you have to implement the transport by yourself...