netdev-dpdk: fix mbuf leaks
[cascardo/ovs.git] / datapath-windows / DESIGN
1                        OVS-on-Hyper-V Design Document
2                        ==============================
3 There has been a community effort to develop Open vSwitch on Microsoft Hyper-V.
4 In this document, we provide details of the development effort. We believe this
5 document should give enough information to understand the overall design.
6
7 The userspace portion of the OVS has been ported to Hyper-V in a separate
8 effort, and committed to the openvswitch repo. So, this document will mostly
9 emphasize on the kernel driver, though we touch upon some of the aspects of
10 userspace as well.
11
12 We cover the following topics:
13 1. Background into relevant Hyper-V architecture
14 2. Design of the OVS Windows implementation
15    a. Kernel module (datapath)
16    b. Userspace components
17    c. Kernel-Userspace interface
18    d. Flow of a packet
19 3. Build/Deployment environment
20
21 For more questions, please contact dev@openvswitch.org
22
23 1) Background into relevant Hyper-V architecture
24 ------------------------------------------------
25 Microsoft’s hypervisor solution - Hyper-V[1] implements a virtual switch that
26 is extensible and provides opportunities for other vendors to implement
27 functional extensions[2]. The extensions need to be implemented as NDIS drivers
28 that bind within the extensible switch driver stack provided. The extensions
29 can broadly provide the functionality of monitoring, modifying and forwarding
30 packets to destination ports on the Hyper-V extensible switch. Correspondingly,
31 the extensions can be categorized into the following types and provide the
32 functionality noted:
33  * Capturing extensions: monitoring packets
34  * Filtering extensions: monitoring, modifying packets
35  * Forwarding extensions: monitoring, modifying, forwarding packets
36
37 As can be expected, the kernel portion (datapath) of OVS on Hyper-V solution
38 will be implemented as a forwarding extension.
39
40 In Hyper-V, the virtual machine is called the Child Partition. Each VIF or
41 physical NIC on the Hyper-V extensible switch is attached via a port. Each port
42 is both on the ingress path or the egress path of the switch. The ingress path
43 is used for packets being sent out of a port, and egress is used for packet
44 being received on a port. By design, NDIS provides a layered interface. In this
45 layered interface, higher level layers call into lower level layers, in the
46 ingress path. In the egress path, it is the other way round. In addition, there
47 is a object identifier (OID) interface for control operations Eg. addition of
48 a port. The workflow for the calls is similar in nature to the packets, where
49 higher level layers call into the lower level layers. A good representational
50 diagram of this architecture is in [4].
51
52 Windows Filtering Platform (WFP)[5] is a platform implemented on Hyper-V that
53 provides APIs and services for filtering packets. WFP has been utilized to
54 filter on some of the packets that OVS is not equipped to handle directly. More
55 details in later sections.
56
57 IP Helper [6] is a set of API available on Hyper-V to retrieve information
58 related to the network configuration information on the host machine. IP Helper
59 has been used to retrieve some of the configuration information that OVS needs.
60
61
62 2) Design of the OVS Windows implementation
63 -------------------------------------------
64
65                                   +-------------------------------+
66                                   |                               |
67                                   |        CHILD PARTITION        |
68                                   |                               |
69   +------+ +--------------+       | +-----------+  +------------+ |
70   |      | |              |       | |           |  |            | |
71   | ovs- | |     OVS-     |       | | Virtual   |  | Virtual    | |
72   | *ctl | |  USERSPACE   |       | | Machine #1|  | Machine #2 | |
73   |      | |    DAEMON    |       | |           |  |            | |
74   +------+-++---+---------+       | +--+------+-+  +----+------++ | +--------+
75   |  dpif-  |   | netdev- |       |    |VIF #1|         |VIF #2|  | |Physical|
76   | netlink |   | windows |       |    +------+         +------+  | |  NIC   |
77   +---------+   +---------+       |      ||                   /\  | +--------+
78 User     /\         /\            |      || *#1*         *#4* ||  |     /\
79 =========||=========||============+------||-------------------||--+     ||
80 Kernel   ||         ||                   \/                   ||  ||=====/
81          \/         \/                +-----+                 +-----+ *#5*
82  +-------------------------------+    |     |                 |     |
83  |   +----------------------+    |    |     |                 |     |
84  |   |   OVS Pseudo Device  |    |    |     |                 |     |
85  |   +----------------------+    |    |     |                 |     |
86  |      | Netlink Impl. |        |    |     |                 |     |
87  |      -----------------        |    |  I  |                 |     |
88  | +------------+                |    |  N  |                 |  E  |
89  | |  Flowtable | +------------+ |    |  G  |                 |  G  |
90  | +------------+ |  Packet    | |*#2*|  R  |                 |  R  |
91  |   +--------+   | Processing | |<=> |  E  |                 |  E  |
92  |   |   WFP  |   |            | |    |  S  |                 |  S  |
93  |   | Driver |   +------------+ |    |  S  |                 |  S  |
94  |   +--------+                  |    |     |                 |     |
95  |                               |    |     |                 |     |
96  |   OVS FORWARDING EXTENSION    |    |     |                 |     |
97  +-------------------------------+    +-----+-----------------+-----+
98                                       |HYPER-V Extensible Switch *#3|
99                                       +-----------------------------+
100                                                NDIS STACK
101
102   Fig 2. Various blocks of the OVS Windows implementation
103
104 Figure 2 shows the various blocks involved in the OVS Windows implementation,
105 along with some of the components available in the NDIS stack, and also the
106 virtual machines. The workflow of a packet being transmitted from a VIF out and
107 into another VIF and to a physical NIC is also shown. Later on in this section,
108 we will discuss the flow of a packet at a high level.
109
110 The figure gives a general idea of where the OVS userspace and the kernel
111 components fit in, and how they interface with each other.
112
113 The kernel portion (datapath) of OVS on Hyper-V solution has be implemented as
114 a forwarding extension roughly implementing the following
115 sub-modules/functionality. Details of each of these sub-components in the
116 kernel are contained in later sections:
117  * Interfacing with the NDIS stack
118  * Netlink message parser
119  * Netlink sockets
120  * Switch/Datapath management
121  * Interfacing with userspace portion of the OVS solution to implement the
122    necessary functionality that userspace needs
123  * Port management
124  * Flowtable/Actions/packet forwarding
125  * Tunneling
126  * Event notifications
127
128 The datapath for the OVS on Linux is a kernel module, and cannot be directly
129 ported since there are significant differences in architecture even though the
130 end functionality provided would be similar. Some examples of the differences
131 are:
132  * Interfacing with the NDIS stack to hook into the NDIS callbacks for
133    functionality such as receiving and sending packets, packet completions,
134    OIDs used for events such as a new port appearing on the virtual switch.
135  * Interface between the userspace and the kernel module.
136  * Event notifications are significantly different.
137  * The communication interface between DPIF and the kernel module need not be
138    implemented in the way OVS on Linux does. That said, it would be
139    advantageous to have a similar interface to the kernel module for reasons of
140    readability and maintainability.
141  * Any licensing issues of using Linux kernel code directly.
142
143 Due to these differences, it was a straightforward decision to develop the
144 datapath for OVS on Hyper-V from scratch rather than porting the one on Linux.
145 A re-development focused on the following goals:
146  * Adhere to the existing requirements of userspace portion of OVS (such as
147    ovs-vswitchd), to minimize changes in the userspace workflow.
148  * Fit well into the typical workflow of a Hyper-V extensible switch forwarding
149    extension.
150
151 The userspace portion of the OVS solution is mostly POSIX code, and not very
152 Linux specific. Majority of the userspace code does not interface directly with
153 the kernel datapath and was ported independently of the kernel datapath
154 effort.
155
156 As explained in the OVS porting design document [7], DPIF is the portion of
157 userspace that interfaces with the kernel portion of the OVS. The interface
158 that each DPIF provider has to implement is defined in dpif-provider.h [3].
159 Though each platform is allowed to have its own implementation of the DPIF
160 provider, it was found, via community feedback, that it is desired to
161 share code whenever possible. Thus, the DPIF provider for OVS on Hyper-V shares
162 code with the DPIF provider on Linux. This interface is implemented in
163 dpif-netlink.c, formerly dpif-linux.c.
164
165 We'll elaborate more on kernel-userspace interface in a dedicated section
166 below. Here it suffices to say that the DPIF provider implementation for
167 Windows is netlink-based and shares code with the Linux one.
168
169 2.a) Kernel module (datapath)
170 -----------------------------
171
172 Interfacing with the NDIS stack
173 -------------------------------
174 For each virtual switch on Hyper-V, the OVS extensible switch extension can be
175 enabled/disabled. We support enabling the OVS extension on only one switch.
176 This is consistent with using a single datapath in the kernel on Linux. All the
177 physical adapters are connected as external adapters to the extensible switch.
178
179 When the OVS switch extension registers itself as a filter driver, it also
180 registers callbacks for the switch/port management and datapath functions. In
181 other words, when a switch is created on the Hyper-V root partition (host), the
182 extension gets an activate callback upon which it can initialize the data
183 structures necessary for OVS to function. Similarly, there are callbacks for
184 when a port gets added to the Hyper-V switch, and an External Network adapter
185 or a VM Network adapter is connected/disconnected to the port. There are also
186 callbacks for when a VIF (NIC of a child partition) send out a packet, or a
187 packet is received on an external NIC.
188
189 As shown in the figures, an extensible switch extension gets to see a packet
190 sent by the VM (VIF) twice - once on the ingress path and once on the egress
191 path. Forwarding decisions are to be made on the ingress path. Correspondingly,
192 we will be hooking onto the following interfaces:
193  * Ingress send indication: intercept packets for performing flow based
194    forwarding.This includes straight forwarding to output ports. Any packet
195    modifications needed to be performed are done here either inline or by
196    creating a new packet. A forwarding action is performed as the flow actions
197    dictate.
198  * Ingress completion indication: cleanup and free packets that we generated on
199    the ingress send path, pass-through for packets that we did not generate.
200  * Egress receive indication: pass-through.
201  * Egress completion indication: pass-through.
202
203 Interfacing with OVS userspace
204 ------------------------------
205 We have implemented a pseudo device interface for letting OVS userspace talk to
206 the OVS kernel module. This is equivalent to the typical character device
207 interface on POSIX platforms where we can register custom functions for read,
208 write and ioctl functionality. The pseudo device supports a whole bunch of
209 ioctls that netdev and DPIF on OVS userspace make use of.
210
211 Netlink message parser
212 ----------------------
213 The communication between OVS userspace and OVS kernel datapath is in the form
214 of Netlink messages [1]. More details about this are provided in #2.c section,
215 kernel-userspace interface. In the kernel, a full fledged netlink message
216 parser has been implemented along the lines of the netlink message parser in
217 OVS userspace. In fact, a lot of the code is ported code.
218
219 On the lines of 'struct ofpbuf' in OVS userspace, a managed buffer has been
220 implemented in the kernel datapath to make it easier to parse and construct
221 netlink messages.
222
223 Netlink sockets
224 ---------------
225 On Linux, OVS userspace utilizes netlink sockets to pass back and forth netlink
226 messages. Since much of userspace code including DPIF provider in
227 dpif-netlink.c (formerly dpif-linux.c) has been reused, pseudo-netlink sockets
228 have been implemented in OVS userspace. As it is known, Windows lacks native
229 netlink socket support, and also the socket family is not extensible either.
230 Hence it is not possible to provide a native implementation of netlink socket.
231 We emulate netlink sockets in lib/netlink-socket.c and support all of the nl_*
232 APIs to higher levels. The implementation opens a handle to the pseudo device
233 for each netlink socket. Some more details on this topic are provided in the
234 userspace section on netlink sockets.
235
236 Typical netlink semantics of read message, write message, dump, and transaction
237 have been implemented so that higher level layers are not affected by the
238 netlink implementation not being native.
239
240 Switch/Datapath management
241 --------------------------
242 As explained above, we hook onto the management callback functions in the NDIS
243 interface for when to initialize the OVS data structures, flow tables etc. Some
244 of this code is also driven by OVS userspace code which sends down ioctls for
245 operations like creating a tunnel port etc.
246
247 Port management
248 ---------------
249 As explained above, we hook onto the management callback functions in the NDIS
250 interface to know when a port is added/connected to the Hyper-V switch. We use
251 these callbacks to initialize the port related data structures in OVS. Also,
252 some of the ports are tunnel ports that don’t exist on the Hyper-V switch and
253 get added from OVS userspace.
254
255 In order to identify a Hyper-V port, we use the value of 'FriendlyName' field
256 in each Hyper-V port. We call this the "OVS-port-name". The idea is that OVS
257 userspace sets 'OVS-port-name' in each Hyper-V port to the same value as the
258 'name' field of the 'Interface' table in OVSDB. When OVS userspace calls into
259 the kernel datapath to add a port, we match the name of the port with the
260 'OVS-port-name' of a Hyper-V port.
261
262 We maintain separate hash tables, and separate counters for ports that have
263 been added from the Hyper-V switch, and for ports that have been added from OVS
264 userspace.
265
266 Flowtable/Actions/packet forwarding
267 -----------------------------------
268 The flowtable and flow actions based packet forwarding is the core of the OVS
269 datapath functionality. For each packet on the ingress path, we consult the
270 flowtable and execute the corresponding actions. The actions can be limited to
271 simple forwarding to a particular destination port(s), or more commonly
272 involves modifying the packet to insert a tunnel context or a VLAN ID, and
273 thereafter forwarding to the external port to send the packet to a destination
274 host.
275
276 Tunneling
277 ---------
278 We make use of the Internal Port on a Hyper-V switch for implementing
279 tunneling. The Internal Port is a virtual adapter that is exposed on the Hyper-
280 V host, and connected to the Hyper-V switch. Basically, it is an interface
281 between the host and the virtual switch. The Internal Port acts as the Tunnel
282 end point for the host (aka VTEP), and holds the VTEP IP address.
283
284 Tunneling ports are not actual ports on the Hyper-V switch. These are virtual
285 ports that OVS maintains and while executing actions, if the outport is a
286 tunnel port, we short circuit by performing the encapsulation action based on
287 the tunnel context. The encapsulated packet gets forwarded to the external
288 port, and appears to the outside world as though it was set from the VTEP.
289
290 Similarly, when a tunneled packet enters the OVS from the external port bound
291 to the internal port (VTEP), and if yes, we short circuit the path, and
292 directly forward the inner packet to the destination port (mostly a VIF, but
293 dictated by the flow). We leverage the Windows Filtering Platform (WFP)
294 framework to be able to receive tunneled packets that cannot be decapsulated by
295 OVS right away. Currently, fragmented IP packets fall into that category, and
296 we leverage the code in the host IP stack to reassemble the packet, and
297 performing decapsulation on the reassembled packet.
298
299 We’ll also be using the IP helper library to provide us IP address and other
300 information corresponding to the Internal port.
301
302 Event notifications
303 -------------------
304 The pseudo device interface described above is also used for providing event
305 notifications back to OVS userspace. A shared memory/overlapped IO model is
306 used.
307
308 2.b) Userspace components
309 -------------------------
310 The userspace portion of the OVS solution is mostly POSIX code, and not very
311 Linux specific. Majority of the userspace code does not interface directly with
312 the kernel datapath and was ported independently of the kernel datapath
313 effort.
314
315 In this section, we cover the userspace components that interface with the
316 kernel datapath.
317
318 As explained earlier, OVS on Hyper-V shares the DPIF provider implementation
319 with Linux. The DPIF provider on Linux uses netlink sockets and netlink
320 messages. Netlink sockets and messages are extensively used on Linux to
321 exchange information between userspace and kernel. In order to satisfy these
322 dependencies, netlink socket (pseudo and non-native) and netlink messages
323 are implemented on Hyper-V.
324
325 The following are the major advantages of sharing DPIF provider code:
326 1. Maintenance is simpler:
327    Any change made to the interface defined in dpif-provider.h need not be
328    propagated to multiple implementations. Also, developers familiar with the
329    Linux implementation of the DPIF provider can easily ramp on the Hyper-V
330    implementation as well.
331 2. Netlink messages provides inherent advantages:
332    Netlink messages are known for their extensibility. Each message is
333    versioned, so the provided data structures offer a mechanism to perform
334    version checking and forward/backward compatibility with the kernel
335    module.
336
337 Netlink sockets
338 ---------------
339 As explained in other sections, an emulation of netlink sockets has been
340 implemented in lib/netlink-socket.c for Windows. The implementation creates a
341 handle to the OVS pseudo device, and emulates netlink socket semantics of
342 receive message, send message, dump, and transact. Most of the nl_* functions
343 are supported.
344
345 The fact that the implementation is non-native manifests in various ways.
346 One example is that PID for the netlink socket is not automatically assigned in
347 userspace when a handle is created to the OVS pseudo device. There's an extra
348 command (defined in OvsDpInterfaceExt.h) that is used to grab the PID generated
349 in the kernel.
350
351 DPIF provider
352 --------------
353 As has been mentioned in earlier sections, the netlink socket and netlink
354 message based DPIF provider on Linux has been ported to Windows.
355 Correspondingly, the file is called lib/dpif-netlink.c now from its former
356 name of lib/dpif-linux.c.
357
358 Most of the code is common. Some divergence is in the code to receive
359 packets. The Linux implementation uses epoll() which is not natively supported
360 on Windows.
361
362 Netdev-Windows
363 --------------
364 We have a Windows implementation of the interface defined in
365 lib/netdev-provider.h. The implementation provides functionality to get
366 extended information about an interface. It is limited in functionality
367 compared to the Linux implementation of the netdev provider and cannot be used
368 to add any interfaces in the kernel such as a tap interface or to send/receive
369 packets. The netdev-windows implementation uses the datapath interface
370 extensions defined in:
371 datapath-windows/include/OvsDpInterfaceExt.h
372
373 Powershell extensions to set "OVS-port-name"
374 --------------------------------------------
375 As explained in the section on "Port management", each Hyper-V port has a
376 'FriendlyName' field, which we call as the "OVS-port-name" field. We have
377 implemented powershell command extensions to be able to set the "OVS-port-name"
378 of a Hyper-V port.
379
380 2.c) Kernel-Userspace interface
381 -------------------------------
382 openvswitch.h and OvsDpInterfaceExt.h
383 -------------------------------------
384 Since the DPIF provider is shared with Linux, the kernel datapath provides the
385 same interface as the Linux datapath. The interface is defined in
386 datapath/linux/compat/include/linux/openvswitch.h. Derivatives of this
387 interface file are created during OVS userspace compilation. The derivative for
388 the kernel datapath on Hyper-V is provided in the following location:
389 datapath-windows/include/OvsDpInterface.h
390
391 That said, there are Windows specific extensions that are defined in the
392 interface file:
393 datapath-windows/include/OvsDpInterfaceExt.h
394
395 2.d) Flow of a packet
396 ---------------------
397 Figure 2 shows the numbered steps in which a packets gets sent out of a VIF and
398 is forwarded to another VIF or a physical NIC. As mentioned earlier, each VIF
399 is attached to the switch via a port, and each port is both on the ingress and
400 egress path of the switch, and depending on whether a packet is being
401 transmitted or received, one of the paths gets used. In the figure, each step n
402 is annotated as *#n*
403
404 The steps are as follows:
405 1. When a packet is sent out of a VIF or an physical NIC or an internal port,
406 the packet is part of the ingress path.
407 2. The OVS kernel driver gets to intercept this packet.
408    a. OVS looks up the flows in the flowtable for this packet, and executes the
409       corresponding action.
410    b. If there is not action, the packet is sent up to OVS userspace to examine
411       the packet and figure out the actions.
412    v. Userspace executes the packet by specifying the actions, and might also
413       insert a flow for such a packet in the future.
414    d. The destination ports are added to the packet and sent down to the Hyper-
415       V switch.
416 3. The Hyper-V forwards the packet to the destination ports specified in the
417 packet, and sends it out on the egress path.
418 4. The packet gets forwarded to the destination VIF.
419 5. It might also get forwarded to a physical NIC as well, if the physical NIC
420 has been added as a destination port by OVS.
421
422
423 3) Build/Deployment:
424 --------------------
425 The userspace components added as part of OVS Windows implementation have been
426 integrated with autoconf, and can be built using the steps mentioned in the
427 BUILD.Windows file. Additional targets need to be specified to make.
428
429 The OVS kernel code is part of a Visual Studio 2013 solution, and is compiled
430 from the IDE. There are plans in the future to move this to a compilation mode
431 such that we can compile it without an IDE as well.
432
433 Once compiled, we have an install script that can be used to load the kernel
434 driver.
435
436
437 Reference list:
438 ===============
439 1. Hyper-V Extensible Switch
440 http://msdn.microsoft.com/en-us/library/windows/hardware/hh598161(v=vs.85).aspx
441 2. Hyper-V Extensible Switch Extensions
442 http://msdn.microsoft.com/en-us/library/windows/hardware/hh598169(v=vs.85).aspx
443 3. DPIF Provider
444 http://openvswitch.sourcearchive.com/documentation/1.1.0-1/dpif-
445 provider_8h_source.html
446 4. Hyper-V Extensible Switch Components
447 http://msdn.microsoft.com/en-us/library/windows/hardware/hh598163(v=vs.85).aspx
448 5. Windows Filtering Platform
449 http://msdn.microsoft.com/en-us/library/windows/desktop/aa366510(v=vs.85).aspx
450 6. IP Helper
451 http://msdn.microsoft.com/en-us/library/windows/hardware/ff557015(v=vs.85).aspx
452 7. How to Port Open vSwitch to New Software or Hardware
453 http://git.openvswitch.org/cgi-bin/gitweb.cgi?p=openvswitch;a=blob;f=PORTING
454 8. Netlink
455 http://en.wikipedia.org/wiki/Netlink
456 9. epoll
457 http://en.wikipedia.org/wiki/Epoll