xref: /linux/Documentation/bpf/map_xskmap.rst (revision 9a87ffc99ec8eb8d35eed7c4f816d75f5cc9662e)
12b3e8f6fSMaryam Tahhan.. SPDX-License-Identifier: GPL-2.0-only
22b3e8f6fSMaryam Tahhan.. Copyright (C) 2022 Red Hat, Inc.
32b3e8f6fSMaryam Tahhan
42b3e8f6fSMaryam Tahhan===================
52b3e8f6fSMaryam TahhanBPF_MAP_TYPE_XSKMAP
62b3e8f6fSMaryam Tahhan===================
72b3e8f6fSMaryam Tahhan
82b3e8f6fSMaryam Tahhan.. note::
92b3e8f6fSMaryam Tahhan   - ``BPF_MAP_TYPE_XSKMAP`` was introduced in kernel version 4.18
102b3e8f6fSMaryam Tahhan
112b3e8f6fSMaryam TahhanThe ``BPF_MAP_TYPE_XSKMAP`` is used as a backend map for XDP BPF helper
122b3e8f6fSMaryam Tahhancall ``bpf_redirect_map()`` and ``XDP_REDIRECT`` action, like 'devmap' and 'cpumap'.
132b3e8f6fSMaryam TahhanThis map type redirects raw XDP frames to `AF_XDP`_ sockets (XSKs), a new type of
142b3e8f6fSMaryam Tahhanaddress family in the kernel that allows redirection of frames from a driver to
152b3e8f6fSMaryam Tahhanuser space without having to traverse the full network stack. An AF_XDP socket
162b3e8f6fSMaryam Tahhanbinds to a single netdev queue. A mapping of XSKs to queues is shown below:
172b3e8f6fSMaryam Tahhan
182b3e8f6fSMaryam Tahhan.. code-block:: none
192b3e8f6fSMaryam Tahhan
202b3e8f6fSMaryam Tahhan    +---------------------------------------------------+
212b3e8f6fSMaryam Tahhan    |     xsk A      |     xsk B       |      xsk C     |<---+ User space
222b3e8f6fSMaryam Tahhan    =========================================================|==========
232b3e8f6fSMaryam Tahhan    |    Queue 0     |     Queue 1     |     Queue 2    |    |  Kernel
242b3e8f6fSMaryam Tahhan    +---------------------------------------------------+    |
252b3e8f6fSMaryam Tahhan    |                  Netdev eth0                      |    |
262b3e8f6fSMaryam Tahhan    +---------------------------------------------------+    |
272b3e8f6fSMaryam Tahhan    |                            +=============+        |    |
282b3e8f6fSMaryam Tahhan    |                            | key |  xsk  |        |    |
292b3e8f6fSMaryam Tahhan    |  +---------+               +=============+        |    |
302b3e8f6fSMaryam Tahhan    |  |         |               |  0  | xsk A |        |    |
312b3e8f6fSMaryam Tahhan    |  |         |               +-------------+        |    |
322b3e8f6fSMaryam Tahhan    |  |         |               |  1  | xsk B |        |    |
332b3e8f6fSMaryam Tahhan    |  | BPF     |-- redirect -->+-------------+-------------+
342b3e8f6fSMaryam Tahhan    |  | prog    |               |  2  | xsk C |        |
352b3e8f6fSMaryam Tahhan    |  |         |               +-------------+        |
362b3e8f6fSMaryam Tahhan    |  |         |                                      |
372b3e8f6fSMaryam Tahhan    |  |         |                                      |
382b3e8f6fSMaryam Tahhan    |  +---------+                                      |
392b3e8f6fSMaryam Tahhan    |                                                   |
402b3e8f6fSMaryam Tahhan    +---------------------------------------------------+
412b3e8f6fSMaryam Tahhan
422b3e8f6fSMaryam Tahhan.. note::
432b3e8f6fSMaryam Tahhan    An AF_XDP socket that is bound to a certain <netdev/queue_id> will *only*
442b3e8f6fSMaryam Tahhan    accept XDP frames from that <netdev/queue_id>. If an XDP program tries to redirect
452b3e8f6fSMaryam Tahhan    from a <netdev/queue_id> other than what the socket is bound to, the frame will
462b3e8f6fSMaryam Tahhan    not be received on the socket.
472b3e8f6fSMaryam Tahhan
482b3e8f6fSMaryam TahhanTypically an XSKMAP is created per netdev. This map contains an array of XSK File
492b3e8f6fSMaryam TahhanDescriptors (FDs). The number of array elements is typically set or adjusted using
502b3e8f6fSMaryam Tahhanthe ``max_entries`` map parameter. For AF_XDP ``max_entries`` is equal to the number
512b3e8f6fSMaryam Tahhanof queues supported by the netdev.
522b3e8f6fSMaryam Tahhan
532b3e8f6fSMaryam Tahhan.. note::
542b3e8f6fSMaryam Tahhan    Both the map key and map value size must be 4 bytes.
552b3e8f6fSMaryam Tahhan
562b3e8f6fSMaryam TahhanUsage
572b3e8f6fSMaryam Tahhan=====
582b3e8f6fSMaryam Tahhan
592b3e8f6fSMaryam TahhanKernel BPF
602b3e8f6fSMaryam Tahhan----------
612b3e8f6fSMaryam Tahhanbpf_redirect_map()
622b3e8f6fSMaryam Tahhan^^^^^^^^^^^^^^^^^^
632b3e8f6fSMaryam Tahhan.. code-block:: c
642b3e8f6fSMaryam Tahhan
652b3e8f6fSMaryam Tahhan    long bpf_redirect_map(struct bpf_map *map, u32 key, u64 flags)
662b3e8f6fSMaryam Tahhan
672b3e8f6fSMaryam TahhanRedirect the packet to the endpoint referenced by ``map`` at index ``key``.
682b3e8f6fSMaryam TahhanFor ``BPF_MAP_TYPE_XSKMAP`` this map contains references to XSK FDs
692b3e8f6fSMaryam Tahhanfor sockets attached to a netdev's queues.
702b3e8f6fSMaryam Tahhan
712b3e8f6fSMaryam Tahhan.. note::
722b3e8f6fSMaryam Tahhan    If the map is empty at an index, the packet is dropped. This means that it is
732b3e8f6fSMaryam Tahhan    necessary to have an XDP program loaded with at least one XSK in the
742b3e8f6fSMaryam Tahhan    XSKMAP to be able to get any traffic to user space through the socket.
752b3e8f6fSMaryam Tahhan
762b3e8f6fSMaryam Tahhanbpf_map_lookup_elem()
772b3e8f6fSMaryam Tahhan^^^^^^^^^^^^^^^^^^^^^
782b3e8f6fSMaryam Tahhan.. code-block:: c
792b3e8f6fSMaryam Tahhan
802b3e8f6fSMaryam Tahhan    void *bpf_map_lookup_elem(struct bpf_map *map, const void *key)
812b3e8f6fSMaryam Tahhan
822b3e8f6fSMaryam TahhanXSK entry references of type ``struct xdp_sock *`` can be retrieved using the
832b3e8f6fSMaryam Tahhan``bpf_map_lookup_elem()`` helper.
842b3e8f6fSMaryam Tahhan
852b3e8f6fSMaryam TahhanUser space
862b3e8f6fSMaryam Tahhan----------
872b3e8f6fSMaryam Tahhan.. note::
882b3e8f6fSMaryam Tahhan    XSK entries can only be updated/deleted from user space and not from
892b3e8f6fSMaryam Tahhan    a BPF program. Trying to call these functions from a kernel BPF program will
902b3e8f6fSMaryam Tahhan    result in the program failing to load and a verifier warning.
912b3e8f6fSMaryam Tahhan
922b3e8f6fSMaryam Tahhanbpf_map_update_elem()
932b3e8f6fSMaryam Tahhan^^^^^^^^^^^^^^^^^^^^^
942b3e8f6fSMaryam Tahhan.. code-block:: c
952b3e8f6fSMaryam Tahhan
962b3e8f6fSMaryam Tahhan	int bpf_map_update_elem(int fd, const void *key, const void *value, __u64 flags)
972b3e8f6fSMaryam Tahhan
982b3e8f6fSMaryam TahhanXSK entries can be added or updated using the ``bpf_map_update_elem()``
992b3e8f6fSMaryam Tahhanhelper. The ``key`` parameter is equal to the queue_id of the queue the XSK
1002b3e8f6fSMaryam Tahhanis attaching to. And the ``value`` parameter is the FD value of that socket.
1012b3e8f6fSMaryam Tahhan
1022b3e8f6fSMaryam TahhanUnder the hood, the XSKMAP update function uses the XSK FD value to retrieve the
1032b3e8f6fSMaryam Tahhanassociated ``struct xdp_sock`` instance.
1042b3e8f6fSMaryam Tahhan
1052b3e8f6fSMaryam TahhanThe flags argument can be one of the following:
1062b3e8f6fSMaryam Tahhan
1072b3e8f6fSMaryam Tahhan- BPF_ANY: Create a new element or update an existing element.
1082b3e8f6fSMaryam Tahhan- BPF_NOEXIST: Create a new element only if it did not exist.
1092b3e8f6fSMaryam Tahhan- BPF_EXIST: Update an existing element.
1102b3e8f6fSMaryam Tahhan
1112b3e8f6fSMaryam Tahhanbpf_map_lookup_elem()
1122b3e8f6fSMaryam Tahhan^^^^^^^^^^^^^^^^^^^^^
1132b3e8f6fSMaryam Tahhan.. code-block:: c
1142b3e8f6fSMaryam Tahhan
1152b3e8f6fSMaryam Tahhan    int bpf_map_lookup_elem(int fd, const void *key, void *value)
1162b3e8f6fSMaryam Tahhan
1172b3e8f6fSMaryam TahhanReturns ``struct xdp_sock *`` or negative error in case of failure.
1182b3e8f6fSMaryam Tahhan
1192b3e8f6fSMaryam Tahhanbpf_map_delete_elem()
1202b3e8f6fSMaryam Tahhan^^^^^^^^^^^^^^^^^^^^^
1212b3e8f6fSMaryam Tahhan.. code-block:: c
1222b3e8f6fSMaryam Tahhan
1232b3e8f6fSMaryam Tahhan    int bpf_map_delete_elem(int fd, const void *key)
1242b3e8f6fSMaryam Tahhan
1252b3e8f6fSMaryam TahhanXSK entries can be deleted using the ``bpf_map_delete_elem()``
1262b3e8f6fSMaryam Tahhanhelper. This helper will return 0 on success, or negative error in case of
1272b3e8f6fSMaryam Tahhanfailure.
1282b3e8f6fSMaryam Tahhan
1292b3e8f6fSMaryam Tahhan.. note::
1302b3e8f6fSMaryam Tahhan    When `libxdp`_ deletes an XSK it also removes the associated socket
1312b3e8f6fSMaryam Tahhan    entry from the XSKMAP.
1322b3e8f6fSMaryam Tahhan
1332b3e8f6fSMaryam TahhanExamples
1342b3e8f6fSMaryam Tahhan========
1352b3e8f6fSMaryam TahhanKernel
1362b3e8f6fSMaryam Tahhan------
1372b3e8f6fSMaryam Tahhan
1382b3e8f6fSMaryam TahhanThe following code snippet shows how to declare a ``BPF_MAP_TYPE_XSKMAP`` called
1392b3e8f6fSMaryam Tahhan``xsks_map`` and how to redirect packets to an XSK.
1402b3e8f6fSMaryam Tahhan
1412b3e8f6fSMaryam Tahhan.. code-block:: c
1422b3e8f6fSMaryam Tahhan
1432b3e8f6fSMaryam Tahhan	struct {
1442b3e8f6fSMaryam Tahhan		__uint(type, BPF_MAP_TYPE_XSKMAP);
1452b3e8f6fSMaryam Tahhan		__type(key, __u32);
1462b3e8f6fSMaryam Tahhan		__type(value, __u32);
1472b3e8f6fSMaryam Tahhan		__uint(max_entries, 64);
1482b3e8f6fSMaryam Tahhan	} xsks_map SEC(".maps");
1492b3e8f6fSMaryam Tahhan
1502b3e8f6fSMaryam Tahhan
1512b3e8f6fSMaryam Tahhan	SEC("xdp")
1522b3e8f6fSMaryam Tahhan	int xsk_redir_prog(struct xdp_md *ctx)
1532b3e8f6fSMaryam Tahhan	{
1542b3e8f6fSMaryam Tahhan		__u32 index = ctx->rx_queue_index;
1552b3e8f6fSMaryam Tahhan
1562b3e8f6fSMaryam Tahhan		if (bpf_map_lookup_elem(&xsks_map, &index))
1572b3e8f6fSMaryam Tahhan			return bpf_redirect_map(&xsks_map, index, 0);
1582b3e8f6fSMaryam Tahhan		return XDP_PASS;
1592b3e8f6fSMaryam Tahhan	}
1602b3e8f6fSMaryam Tahhan
1612b3e8f6fSMaryam TahhanUser space
1622b3e8f6fSMaryam Tahhan----------
1632b3e8f6fSMaryam Tahhan
1642b3e8f6fSMaryam TahhanThe following code snippet shows how to update an XSKMAP with an XSK entry.
1652b3e8f6fSMaryam Tahhan
1662b3e8f6fSMaryam Tahhan.. code-block:: c
1672b3e8f6fSMaryam Tahhan
1682b3e8f6fSMaryam Tahhan	int update_xsks_map(struct bpf_map *xsks_map, int queue_id, int xsk_fd)
1692b3e8f6fSMaryam Tahhan	{
1702b3e8f6fSMaryam Tahhan		int ret;
1712b3e8f6fSMaryam Tahhan
1722b3e8f6fSMaryam Tahhan		ret = bpf_map_update_elem(bpf_map__fd(xsks_map), &queue_id, &xsk_fd, 0);
1732b3e8f6fSMaryam Tahhan		if (ret < 0)
1742b3e8f6fSMaryam Tahhan			fprintf(stderr, "Failed to update xsks_map: %s\n", strerror(errno));
1752b3e8f6fSMaryam Tahhan
1762b3e8f6fSMaryam Tahhan		return ret;
1772b3e8f6fSMaryam Tahhan	}
1782b3e8f6fSMaryam Tahhan
1792b3e8f6fSMaryam TahhanFor an example on how create AF_XDP sockets, please see the AF_XDP-example and
1802b3e8f6fSMaryam TahhanAF_XDP-forwarding programs in the `bpf-examples`_ directory in the `libxdp`_ repository.
181*1d3cab43SRandy DunlapFor a detailed explanation of the AF_XDP interface please see:
1822b3e8f6fSMaryam Tahhan
1832b3e8f6fSMaryam Tahhan- `libxdp-readme`_.
1842b3e8f6fSMaryam Tahhan- `AF_XDP`_ kernel documentation.
1852b3e8f6fSMaryam Tahhan
1862b3e8f6fSMaryam Tahhan.. note::
1872b3e8f6fSMaryam Tahhan    The most comprehensive resource for using XSKMAPs and AF_XDP is `libxdp`_.
1882b3e8f6fSMaryam Tahhan
1892b3e8f6fSMaryam Tahhan.. _libxdp: https://github.com/xdp-project/xdp-tools/tree/master/lib/libxdp
1902b3e8f6fSMaryam Tahhan.. _AF_XDP: https://www.kernel.org/doc/html/latest/networking/af_xdp.html
1912b3e8f6fSMaryam Tahhan.. _bpf-examples: https://github.com/xdp-project/bpf-examples
1922b3e8f6fSMaryam Tahhan.. _libxdp-readme: https://github.com/xdp-project/xdp-tools/tree/master/lib/libxdp#using-af_xdp-sockets
193