How to Port Open vSwitch to New Software or Hardware ==================================================== Open vSwitch (OVS) is intended to be easily ported to new software and hardware platforms. This document describes the types of changes that are most likely to be necessary in porting OVS to Unix-like platforms. (Porting OVS to other kinds of platforms is likely to be more difficult.) Open vSwitch Architectural Overview ----------------------------------- The following diagram shows the conceptual architecture of Open vSwitch from a porter's perspective. _ _ | +-------------------+ | | | ovs-vswitchd | |Generic | +-------------------+ |code userspace | | ofproto | _| | +---------+---------+ _ | | netdev |dpif/wdp | | |_ +---||----+----||---+ |Code that _ || || |may need | +---||-----+---||---+ |porting | | |datapath| _| kernel | | +--------+ | | | |_ +-------||----------+ || physical NIC Some of the components are generic. Modulo bugs, these components should not need to be modified as part of a port: - Near the top of the diagram, "ofproto" is the library in Open vSwitch that contains the core OpenFlow protocol implementation and switching functionality. It is built from source files in the "ofproto" directory. - Above ofproto, "ovs-vswitchd", the main Open vSwitch userspace program, is the primary client for ofproto. It is built from source files in the "vswitchd" directory of the Open vSwitch distribution. ovs-vswitchd is the most sophisticated of ofproto's clients, but ofproto can have other clients as well. Notably, ovs-openflowd, in the utilities directory, is much simpler (though less capable) than ovs-vswitchd, and it may be easier to get up and running as part of a port. The other components require attention during a port: - "dpif" or "wdp" is what ofproto uses to directly monitor and control a "datapath", which is the term used in OVS for a collection of physical or virtual ports that are exposed over OpenFlow as a single switch. A datapath implements a flow table. - "netdev" is the interface to "network devices", e.g. eth0 on Linux. ofproto expects that every port exposed by a datapath has a corresponding netdev that it can open with netdev_open(). The following sections talk about these components in more detail. Which Branch? ------------- The architectural diagram shows "dpif" and "wdp" as alternatives. These alternatives correspond to the "master" and "wdp" branches, respectively, of the Open vSwitch Git repository at git://openvswitch.org/openvswitch. Both of these branches currently represent reasonable porting targets for different purposes: - The "master" branch is more mature and better tested. Open vSwitch releases are made from this branch, and most OVS development and testing occurs on this branch. - The "wdp" branch has a software architecture that can take advantage of hardware with support for wildcards (e.g. TCAMs or similar). This branch has known important bugs, but is the basis of a few ongoing hardware projects, so we expect the quality to improve rapidly. Since its architecture is better, in the medium to long term we will fix the problems in the "wdp" branch and merge it into "master". In porting OVS, the major difference between the two branches is the form of the flow table in the datapath: - On "master", the "dpif" datapath interface maintains a simple flow table, one that does not support any kind of wildcards. This flow table essentially acts as a cache. When a packet arrives on an interface, the datapath looks for it in this exact-match table. If there is a match, then it performs the associated actions. If there is no match, the datapath passes the packet up to "ofproto", which maintains a flow table that supports wildcards. If the packet matches in this flow table, then ofproto executes its actions and inserts a new exact-match entry into the dpif flow table. (Otherwise, ofproto sends the packet to the OpenFlow controller, if one is configured.) Thus, on the "master" branch, the datapath has little opportunity to take advantage of hardware support for wildcards, since it is only ever presented with exact-match flow entries. - On "wdp", the "wdp" datapath interface maintains a flow table similar to that of OpenFlow, one that supports wildcards. Thus, a wdp datapath can take advantage of hardware support for wildcards, since it is free to implement the flow table any way it likes. The following sections describe the two datapath interfaces in a little more detail. dpif: The "master" Branch Datapath ---------------------------------- struct dpif_class, in lib/dpif-provider.h, defines the interfaces required to implement a dpif for new hardware or software. That structure contains many function pointers, each of which has a comment that is meant to describe its behavior in detail. If the requirements are unclear, please report this as a bug and we will clarify. There are two existing dpif implementations that may serve as useful examples during a port: * lib/dpif-linux.c is a Linux-specific dpif implementation that talks to an Open vSwitch-specific kernel module (whose sources are in the "datapath" directory). The kernel module performs all of the switching work, passing packets that do not match any flow table entry up to userspace. This dpif implementation is essentially a wrapper around calls to "ioctl". * lib/dpif-netdev.c is a generic dpif implementation that performs all switching internally. It delegates most of its work to the "netdev" library (described below). Using dpif-netdev, instead of writing a new dpif, can be a simple way to get OVS up and running on new platforms, but other solutions are likely to yield higher performance. "wdp": The "wdp" Branch Datapath -------------------------------- struct wdp_class, in ofproto/wdp-provider.h, defines the interfaces required to implement a wdp ("wildcarded datapath") for new hardware or software. That structure contains many function pointers, each of which has a comment that is meant to describe its behavior in detail. If the requirements are unclear, please report this as a bug and we will clarify. The wdp interface is preliminary. Please let us know if it seems unsuitable for your purpose. We will try to improve it. There is currently only one wdp implementation: * ofproto/wdp-xflow.c is an adaptation of "master" branch code that breaks wildcarded flows up into exact-match flows in the same way that ofproto always does on the "master" branch. It delegates its work to exact-match datapath implementations whose interfaces are identical to "master" branch datapaths, except that names have been changed from "dpif" to "xfif" ("exact-match flow interface") and similar. "netdev": Interface to network devices -------------------------------------- The netdev interface can be roughly divided into functionality for the following purposes: * Functions required to properly implement OpenFlow features. For example, OpenFlow requires the ability to report the Ethernet hardware address of a port. These functions must be implemented for minimally correct operation. * Functions required to implement optional Open vSwitch features. For example, the Open vSwitch support for in-band control requires netdev support for inspecting the TCP/IP stack's ARP table. These functions must be implemented if the corresponding OVS features are to work, but may be omitted initially. * Functions that may be needed in some implementations but not others. The dpif-netdev described above, for example, needs to be able to send and receive packets on a netdev. struct netdev_class, in lib/netdev-provider.h, defines the interfaces required to implement a netdev. That structure contains many function pointers, each of which has a comment that is meant to describe its behavior in detail. If the requirements are unclear, please report this as a bug and we will clarify. The existing netdev implementations may serve as useful examples during a port: * lib/netdev-linux.c implements netdev functionality for Linux network devices, using Linux kernel calls. It may be a good place to start for full-featured netdev implementations. * lib/netdev-gre.c and lib/netdev-patch.c are minimal implementations for "virtual ports" implemented by the Open vSwitch datapath module for the Linux kernel. They may serve as a model for minimal netdev implementations. Miscellaneous Notes ------------------- lib/uuid.c, used in OVSDB, assumes that it can obtain a high-quality random number seed at startup by reading from /dev/urandom. You may need to modify it if this is not true on your platform. Questions --------- Please direct porting questions to dev@openvswitch.org. We will try to use questions to improve this porting guide.