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.) Vocabulary ---------- For historical reasons, different words are used for essentially the same concept in different areas of the Open vSwitch source tree. Here is a concordance, indexed by the area of the source tree: datapath/ vport --- vswitchd/ iface port ofproto/ port bundle lib/bond.c slave bond lib/lacp.c slave lacp lib/netdev.c netdev --- database Interface Port Open vSwitch Architectural Overview ----------------------------------- The following diagram shows the very high-level architecture of Open vSwitch from a porter's perspective. +-------------------+ | ovs-vswitchd |<-->ovsdb-server +-------------------+ | ofproto |<-->OpenFlow controllers +--------+-+--------+ | netdev | | ofproto| +--------+ |provider| | netdev | +--------+ |provider| +--------+ Some of the components are generic. Modulo bugs or inadequacies, these components should not need to be modified as part of a port: - "ovs-vswitchd" is the main Open vSwitch userspace program, in vswitchd/. It reads the desired Open vSwitch configuration from the ovsdb-server program over an IPC channel and passes this configuration down to the "ofproto" library. It also passes certain status and statistical information from ofproto back into the database. - "ofproto" is the Open vSwitch library, in ofproto/, that implements an OpenFlow switch. It talks to OpenFlow controllers over the network and to switch hardware or software to an "ofproto provider", explained further below. - "netdev" is the Open vSwitch library, in lib/netdev.c, that abstracts interacting with network devices, that is, Ethernet interfaces. The netdev library is a thin layer over "netdev provider" code, explained further below. The other components may need attention during a port. You will almost certainly have to implement a "netdev provider". Depending on the type of port you are doing and the desired performance, you may also have to implement an "ofproto provider" or a lower-level component called a "dpif" provider. The following sections talk about these components in more detail. Writing a netdev Provider ------------------------- A "netdev provider" implements an operating system and hardware specific interface to "network devices", e.g. eth0 on Linux. Open vSwitch must be able to open each port on a switch as a netdev, so you will need to implement a "netdev provider" that works with your switch hardware and software. 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. The netdev interface can be divided into a few rough categories: * 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 needed in some implementations but not in others. For example, most kinds of ports (see below) do not need functionality to receive packets from a network device. 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-vport.c provides support for "virtual ports" implemented by the Open vSwitch datapath module for the Linux kernel. This may serve as a model for minimal netdev implementations. * lib/netdev-dummy.c is a fake netdev implementation useful only for testing. Porting Strategies ------------------ After a netdev provider has been implemented for a system's network devices, you may choose among three basic porting strategies. The lowest-effort strategy is to use the "userspace switch" implementation built into Open vSwitch. This ought to work, without writing any more code, as long as the netdev provider that you implemented supports receiving packets. It yields poor performance, however, because every packet passes through the ovs-vswitchd process. See INSTALL.userspace for instructions on how to configure a userspace switch. If the userspace switch is not the right choice for your port, then you will have to write more code. You may implement either an "ofproto provider" or a "dpif provider". Which you should choose depends on a few different factors: * Only an ofproto provider can take full advantage of hardware with built-in support for wildcards (e.g. an ACL table or a TCAM). * A dpif provider can take advantage of the Open vSwitch built-in implementations of bonding, LACP, 802.1ag, 802.1Q VLANs, and other features. An ofproto provider has to provide its own implementations, if the hardware can support them at all. * A dpif provider is usually easier to implement. The following sections describe how to implement each kind of port. ofproto Providers ----------------- An "ofproto provider" is what ofproto uses to directly monitor and control an OpenFlow-capable switch. struct ofproto_class, in ofproto/private.h, defines the interfaces to implement a ofproto provider 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. The ofproto provider interface is preliminary. Please let us know if it seems unsuitable for your purpose. We will try to improve it. Writing a dpif Provider ----------------------- Open vSwitch has a built-in ofproto provider named "ofproto-dpif", which is built on top of a library for manipulating datapaths, called "dpif". A "datapath" is a simple flow table, one that supports only exact-match flows, that is, flows without wildcards. When a packet arrives on a network device, 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-dpif, which maintains an OpenFlow flow table (that supports wildcards). If the packet matches in this flow table, then ofproto-dpif executes its actions and inserts a new exact-match entry into the dpif flow table. (Otherwise, ofproto-dpif passes the packet up to ofproto to send the packet to the OpenFlow controller, if one is configured.) The "dpif" library in turn delegates much of its functionality to a "dpif provider". The following diagram shows how dpif providers fit into the Open vSwitch architecture: _ | +-------------------+ | | ovs-vswitchd |<-->ovsdb-server | +-------------------+ | | ofproto |<-->OpenFlow controllers | +--------+-+--------+ _ | | netdev | |ofproto-| | userspace | +--------+ | dpif | | | | netdev | +--------+ | | |provider| | dpif | | | +---||---+ +--------+ | | || | dpif | | implementation of | || |provider| | ofproto provider |_ || +---||---+ | || || | _ +---||-----+---||---+ | | | |datapath| | kernel | | +--------+ _| | | | |_ +--------||---------+ || physical NIC struct dpif_class, in lib/dpif-provider.h, defines the interfaces required to implement a dpif provider 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. 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 into the kernel module. * lib/dpif-netdev.c is a generic dpif implementation that performs all switching internally. This is how the Open vSwitch userspace switch is implemented. Miscellaneous Notes ------------------- Open vSwitch source code uses uint16_t, uint32_t, and uint64_t as fixed-width types in host byte order, and ovs_be16, ovs_be32, and ovs_be64 as fixed-width types in network byte order. Each of the latter is equivalent to the one of the former, but the difference in name makes the intended use obvious. ovs-vswitchd is the most sophisticated of ofproto's clients, but ofproto can have other clients as well. test-openflowd, in the tests directory, is much simpler than ovs-vswitchd. It may be easier to initially bring up test-openflowd as part of a port. lib/entropy.c assumes that it can obtain high-quality random number seeds at startup by reading from /dev/urandom. You will need to modify it if this is not true on your platform. vswitchd/system-stats.c only knows how to obtain some statistics on Linux. Optionally you may implement them for your platform as well. Questions --------- Please direct porting questions to dev@openvswitch.org. We will try to use questions to improve this porting guide.