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