You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The Kernel NIC Interface (KNI) is a DPDK control plane solution that allows userspace applications to exchange packets with the Linux kernel networking stack. See DPDK's [KNI documentation](https://doc.dpdk.org/guides/prog_guide/kernel_nic_interface.html) for more information. This example is a minimum program that can forward packets to and from the Linux kernel.
3
+
The Kernel NIC Interface (KNI) is a DPDK control plane solution that allows userspace applications to exchange packets with the Linux kernel networking stack. See DPDK's [KNI documentation](https://doc.dpdk.org/guides/prog_guide/kernel_nic_interface.html) for more information.
4
4
5
5
## Overview
6
6
7
-
KNI is useful for applications that want to conceptually share the port with the Linux kernel. For example, the application may want to leverage the kernel's built-in ability to handle [ARP](https://tools.ietf.org/html/rfc826) traffic instead of implementing the protocol natively. By enabling KNI for a port, a virtual device with the same name and MAC address as the port is exposed to the Linux kernel. The kernel will be able to receive all packets that are forwarded to this virtual device and the application will receive all packets the kernel sends to it.
7
+
KNI is useful for Capsule applications that want to delegate the processing of various network control plane protocols to either the Linux kernel or other implementations that run on Linux. For example, [Address Resolution Protocol](https://tools.ietf.org/html/rfc826) is the mechanism for hosts to discover each other's link layer address on an IPv4 network. Typically, the Linux kernel handles the ARP discovery for all the network interfaces on the host. However, because Capsule-bound network devices are not visible to the kernel, each Capsule application needs its own ARP implementation, otherwise the network won't be able to route packets to it. Or alternatively, an easier approach is for the application to simply leverage the kernel stack implementation by delegating and forwarding ARP packets via KNI.
8
+
9
+
This example demonstrates said approach by delegating the processing of [Neighbor Discovery Procotol](https://tools.ietf.org/html/rfc4861), the IPv6 equivalent of ARP, to the Linux kernel.
8
10
9
11
## Prerequisite
10
12
11
-
This application requires the kernel module `rte_kni`. Kernel modules are version specific. If you are using our `Vagrant` with `Docker` setup, the module is already preloaded. Otherwise, you will have to compile it by installing the kernel headers or sources required to build kernel modules on your system, then [build `DPDK` from source](https://doc.dpdk.org/guides/linux_gsg/build_dpdk.html).
13
+
This application requires the kernel module `rte_kni`. Kernel modules are version specific. If you are using our Vagrant with Docker setup, the module is already preloaded. Otherwise, you will have to compile it by installing the kernel headers or sources required to build kernel modules on your system, then [build `DPDK` from source](https://doc.dpdk.org/guides/linux_gsg/build_dpdk.html).
12
14
13
15
Once the build is complete, load the module with command:
Finally use `socat` to read from `stdin`, and send the input messages as UDP packets to this IPv6 address. These packets will be routed to the running Capsule application,
Mar 28 19:59:34.805 INFO kni: to kni0: Neighbor Solicitation
71
+
Mar 28 19:59:34.810 INFO kni: from kni0: Neighbor Advertisement
72
+
Mar 28 19:59:34.811 INFO kni: you said: Hello?
73
+
74
+
Mar 28 19:59:39.475 INFO kni: you said: Is there anybody in there?
75
+
43
76
```
44
77
45
78
# Explanation
46
79
47
-
The assigned port `0000:00:08.0` has KNI support turned on by setting the `kni` flag to `true`. To forward packets received on the port to the kernel, the application adds a simple forwarding pipeline by calling `add_pipeline_to_port`. To forward packets received from the kernel through the port, the application adds another forwarding pipeline by calling `add_kni_rx_pipeline_to_port`.
80
+
Capsule leverages the KNI poll mode driver instead of the `librte_kni` API directly. This lets the application to interact with KNI the same way as any other physical or virtual port device.
81
+
82
+
The example is configured with one PCI port, `cap0`, and one KNI port, `kni0`. As new packets arrive through `cap0`'s rx, the application will forward all ICMPv6 packets to the `kni0`'s tx. For the sake of simplicity, it is assumed that all ICMPv6 packets received in this example will be NDP messages, and the application is delegating this link layer address discovery process to the kernel stack. In the reverse direction, kernel stack's NDP responses will come in through `kni0`'s rx, and immediately forwarded out through `cap0`'s tx without modifications. Because we assigned `cap0`'s link layer MAC address, `02:00:00:ff:ff:00`, to `kni0` with the `ip link set` command, the NDP responses already contain the correct link layer information.
83
+
84
+
When `socat` sends out an UDP packet via `eth3` to `kni0`'s IPv6 address `fe80::ff:feff:ff00`, a lookup is performed trying to find the link layer address of the destination. On the very first attempt, that link layer address is not found through the lookup. A neighbor solicitation message is broadcasted instead to initiate the discovery process.
85
+
86
+
`cap0` receives the broadcasted neighbor solicitation message and forwards it to the kernel stack via `kni0`. Kernel responds with a neighbor advertisement message because the IPv6 address matches the address of the `kni0` interface. This response is sent back to `eth3` through `kni0`'s rx then `cap0`'s tx, completing the discovery.
87
+
88
+
The link layer address from the response is cached, all UDP packets are routed to `cap0` with this lookup until the cached entry expires. The Capsule application will receive the UDP packets from `socat`. It parses and prints out the data payload.
0 commit comments