File: af_xdp_dp.rst

package info (click to toggle)
dpdk 24.11.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 121,148 kB
  • sloc: ansic: 2,206,055; python: 11,866; sh: 4,627; makefile: 2,025; awk: 70
file content (342 lines) | stat: -rw-r--r-- 11,135 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
.. SPDX-License-Identifier: BSD-3-Clause
   Copyright(c) 2023 Intel Corporation.

Using the AF_XDP driver in Kubernetes
=====================================

Introduction
------------

Two infrastructure components are needed in order to provision a pod
that is using the AF_XDP PMD in Kubernetes:

1. AF_XDP Device Plugin (DP).
2. AF_XDP Container Network Interface (CNI) binary.

Both of these components are available through
the `AF_XDP Device Plugin for Kubernetes`_ repository.

The AF_XDP DP provisions and advertises networking interfaces to Kubernetes,
while the CNI configures and plumbs network interfaces for the Pod.

This document explains how to use the `AF_XDP Device Plugin for Kubernetes`_
with a DPDK application using the :doc:`../nics/af_xdp`.

.. _AF_XDP Device Plugin for Kubernetes: https://github.com/redhat-et/afxdp-plugins-for-kubernetes


Background
----------

The standard :doc:`../nics/af_xdp` initialization process involves loading an eBPF program
onto the kernel netdev to be used by the PMD.
This operation requires root or escalated Linux privileges
and thus prevents the PMD from working in an unprivileged container.
The AF_XDP Device Plugin handles this situation
by managing the eBPF program(s) on behalf of the Pod, outside of the pod context.

At a technical level the AF_XDP Device Plugin opens a Unix Domain Socket (UDS)
and listens for a client to make requests over that socket.
A DPDK application acting as a client connects and initiates a configuration "handshake".
After some validation on the Device Plugin side,
the client receives a file descriptor which points to the XSKMAP
associated with the loaded eBPF program.
The XSKMAP is an eBPF map of AF_XDP sockets (XSK).
The client can then proceed with creating an AF_XDP socket
and inserting that socket into the XSKMAP pointed to by the descriptor.

The EAL vdev argument ``use_cni`` is used to indicate that the user wishes
to run the PMD in unprivileged mode and to receive the XSKMAP file descriptor
from the CNI.
When this flag is set,
the ``XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD`` libbpf flag
should be used when creating the socket
to instruct libbpf not to load the default libbpf program on the netdev.
Instead the loading is handled by the AF_XDP Device Plugin.

The EAL vdev argument ``use_pinned_map`` is used indicate to the AF_XDP PMD
to retrieve the XSKMAP fd from a pinned eBPF map.
This map is expected to be pinned by an external entity like the AF_XDP Device Plugin.
This enabled unprivileged pods to create and use AF_XDP sockets.
When this flag is set, the ``XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD`` libbpf flag
is used by the AF_XDP PMD when creating the AF_XDP socket.

The EAL vdev argument ``dp_path`` is used alongside the ``use_cni`` or ``use_pinned_map``
arguments to explicitly tell the AF_XDP PMD where to find either:

1. The UDS to interact with the AF_XDP Device Plugin. OR
2. The pinned xskmap to use when creating AF_XDP sockets.

If this argument is not passed alongside the ``use_cni`` or ``use_pinned_map`` arguments
then the AF_XDP PMD configures it internally to the `AF_XDP Device Plugin for Kubernetes`_.

.. note::

   DPDK AF_XDP PMD <= v23.11 will only work with
   the AF_XDP Device Plugin <= commit id `38317c2`_.

.. note::

   DPDK AF_XDP PMD > v23.11 will work with latest version of the AF_XDP Device Plugin
   through a combination of the ``dp_path`` and/or the ``use_cni`` parameter.
   In these versions of the PMD if a user doesn't explicitly set the ``dp_path`` parameter
   when using ``use_cni`` then that path is transparently configured in the AF_XDP PMD
   to the default `AF_XDP Device Plugin for Kubernetes`_ mount point path.
   The path can be overridden by explicitly setting the ``dp_path`` param.

.. note::

   DPDK AF_XDP PMD > v23.11 is backwards compatible
   with (older) versions of the AF_XDP DP <= commit id `38317c2`_
   by explicitly setting ``dp_path`` to ``/tmp/afxdp.sock``.

.. _38317c2: https://github.com/redhat-et/afxdp-plugins-for-kubernetes/commit/38317c256b5c7dfb39e013a0f76010c2ded03669

Prerequisites
-------------

Device Plugin and DPDK container prerequisites:

* Create a DPDK container image.

* Set up the device plugin and prepare the Pod Spec as described in
  the instructions for `AF_XDP Device Plugin for Kubernetes`_.

* The Docker image should contain the libbpf and libxdp libraries,
  which are dependencies for AF_XDP,
  and should include support for the ``ethtool`` command.

* The Pod should have enabled the capabilities
  ``CAP_NET_RAW`` for AF_XDP socket creation,
  ``IPC_LOCK`` for umem creation and
  ``CAP_BPF`` (for Kernel < 5.19) along with support for hugepages.

  .. note::

     For Kernel versions < 5.19, all BPF sys calls required CAP_BPF,
     to access maps shared between the eBFP program and the userspace program.
     Kernels >= 5.19, only requires CAP_BPF for map creation (BPF_MAP_CREATE)
     and loading programs (BPF_PROG_LOAD).

* Increase locked memory limit so containers have enough memory for packet buffers.
  For example:

  .. code-block:: console

     cat << EOF | sudo tee /etc/systemd/system/containerd.service.d/limits.conf
     [Service]
     LimitMEMLOCK=infinity
     EOF

* dpdk-testpmd application should have AF_XDP feature enabled.

  For further information see the docs for the: :doc:`../../nics/af_xdp`.


Example
-------

Build a DPDK container image (using Docker)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

1. Create a Dockerfile (should be placed in top level DPDK directory):

   .. code-block:: console

      FROM fedora:38

      # Setup container to build DPDK applications
      RUN dnf -y upgrade && dnf -y install \
          libbsd-devel \
          numactl-libs \
          libbpf-devel \
          libbpf \
          meson \
          ninja-build \
          libxdp-devel \
          libxdp \
          numactl-devel \
          python3-pyelftools \
          python38 \
          iproute
      RUN dnf groupinstall -y 'Development Tools'

      # Create DPDK dir and copy over sources
      # Create DPDK dir and copy over sources
      COPY ./ /dpdk
      WORKDIR /dpdk

      # Build DPDK
      RUN meson setup build
      RUN ninja -C build

2. Build a DPDK container image (using Docker)

   .. code-block:: console

      # docker build -t dpdk -f Dockerfile

Run dpdk-testpmd with the AF_XDP Device Plugin + CNI
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

* Clone the AF_XDP Device plugin and CNI

  .. code-block:: console

     # git clone https://github.com/redhat-et/afxdp-plugins-for-kubernetes.git

  .. note::

     Ensure you have the AF_XDP Device Plugin + CNI prerequisites installed.

* Build the AF_XDP Device plugin and CNI

  .. code-block:: console

     # cd afxdp-plugins-for-kubernetes/
     # make image

* Make sure to modify the image used by the `daemonset.yml`_ file
  in the deployments directory with the following configuration:

  .. _daemonset.yml : https://github.com/redhat-et/afxdp-plugins-for-kubernetes/blob/main/deployments/daemonset.yml

  .. code-block:: yaml

     image: afxdp-device-plugin:latest

  .. note::

     This will select the AF_XDP DP image that was built locally.
     Detailed configuration options can be found in the AF_XDP Device Plugin `readme`_ .

  .. _readme: https://github.com/redhat-et/afxdp-plugins-for-kubernetes#readme

* Deploy the AF_XDP Device Plugin and CNI

  .. code-block:: console

     # kubectl create -f deployments/daemonset.yml

* Create the Network Attachment definition

  .. code-block:: console

     # kubectl create -f nad.yaml

  Sample nad.yml

  .. code-block:: yaml

     apiVersion: "k8s.cni.cncf.io/v1"
     kind: NetworkAttachmentDefinition
     metadata:
       name: afxdp-network
       annotations:
         k8s.v1.cni.cncf.io/resourceName: afxdp/myPool
     spec:
       config: '{
           "cniVersion": "0.3.0",
           "type": "afxdp",
           "mode": "primary",
           "logFile": "afxdp-cni.log",
           "logLevel": "debug",
           "ethtoolCmds" : ["-N -device- rx-flow-hash udp4 fn",
                            "-N -device- flow-type udp4 dst-port 2152 action 22"
                         ],
           "ipam": {
             "type": "host-local",
             "subnet": "192.168.1.0/24",
             "rangeStart": "192.168.1.200",
             "rangeEnd": "192.168.1.220",
             "routes": [
               { "dst": "0.0.0.0/0" }
             ],
             "gateway": "192.168.1.1"
           }
         }'

  For further reference please use the example provided by the AF_XDP DP `nad.yaml`_

  .. _nad.yaml: https://github.com/redhat-et/afxdp-plugins-for-kubernetes/blob/main/examples/network-attachment-definition.yaml

* Run the Pod

  .. code-block:: console

     # kubectl create -f pod.yaml

  Sample pod.yaml:

  .. code-block:: yaml

     apiVersion: v1
     kind: Pod
     metadata:
      name: dpdk
      annotations:
        k8s.v1.cni.cncf.io/networks: afxdp-network
     spec:
       containers:
       - name: testpmd
         image: dpdk:latest
         command: ["tail", "-f", "/dev/null"]
         securityContext:
           capabilities:
             add:
               - NET_RAW
               - IPC_LOCK
         resources:
           requests:
             afxdp/myPool: '1'
           limits:
             hugepages-1Gi: 2Gi
             cpu: 2
             memory: 256Mi
             afxdp/myPool: '1'
         volumeMounts:
         - name: hugepages
           mountPath: /dev/hugepages
       volumes:
       - name: hugepages
         emptyDir:
           medium: HugePages

  For further reference please see the `pod.yaml`_

  .. _pod.yaml: https://github.com/redhat-et/afxdp-plugins-for-kubernetes/blob/main/examples/pod-spec.yaml

* Run DPDK with a command like the following:

  .. code-block:: console

     kubectl exec -i <Pod name> --container <containers name> -- \
           /<Path>/dpdk-testpmd -l 0,1 --no-pci \
           --vdev=net_af_xdp0,use_cni=1,iface=<interface name> \
           --no-mlockall --in-memory \
           -- -i --a --nb-cores=2 --rxq=1 --txq=1 --forward-mode=macswap;

  Or

  .. code-block:: console

     kubectl exec -i <Pod name> --container <containers name> -- \
           /<Path>/dpdk-testpmd -l 0,1 --no-pci \
           --vdev=net_af_xdp0,use_cni=1,iface=<interface name>,dp_path="/tmp/afxdp_dp/<interface name>/afxdp.sock" \
           --no-mlockall --in-memory \
           -- -i --a --nb-cores=2 --rxq=1 --txq=1 --forward-mode=macswap;

  Or

  .. code-block:: console

     kubectl exec -i <Pod name> --container <containers name> -- \
           /<Path>/dpdk-testpmd -l 0,1 --no-pci \
           --vdev=net_af_xdp0,use_pinned_map=1,iface=<interface name>,dp_path="/tmp/afxdp_dp/<interface name>/xsks_map" \
           --no-mlockall --in-memory \
           -- -i --a --nb-cores=2 --rxq=1 --txq=1 --forward-mode=macswap;

.. note::

   If the ``dp_path`` parameter isn't explicitly set with ``use_cni`` or ``use_pinned_map``
   the AF_XDP PMD will set the parameter values to the `AF_XDP Device Plugin for Kubernetes`_ defaults.