diff options
author | Ilya Maximets <i.maximets@ovn.org> | 2022-12-22 01:06:20 +0100 |
---|---|---|
committer | Ilya Maximets <i.maximets@ovn.org> | 2023-01-03 16:06:21 +0100 |
commit | 1dcc490d44879f33392337dfd9175645fcc4118e (patch) | |
tree | 6308d1212ab5f45dce27136800fde8a1f9e7a371 | |
parent | 0d8318db633fb24936a0f55e869331f0c27f243f (diff) | |
download | openvswitch-1dcc490d44879f33392337dfd9175645fcc4118e.tar.gz |
netdev-afxdp: Allow building with libxdp and newer libbpf.
AF_XDP functions was deprecated in libbpf 0.7 and moved to libxdp.
Functions bpf_get/set_link_xdp_id() was deprecated in libbpf 0.8
and replaced with bpf_xdp_query_id() and bpf_xdp_attach/detach().
Updating configuration and source code to accommodate above changes
and allow building OVS with AF_XDP support on newer systems:
- Checking the version of libbpf by detecting availability
of bpf_xdp_detach.
- Checking availability of the libxdp in a system by looking
for a library providing libxdp_strerror(), if libbpf is
newer than 0.6. And checking for xsk.h header provided by
libxdp-dev[el].
- Use xsk.h from libbpf if it is older than 0.7 and not linking
with libxdp in this case as there are known incompatible
versions of libxdp in distributions.
- Check for the NEED_WAKEUP feature replaced with direct checking
in the source code if XDP_USE_NEED_WAKEUP is defined.
- Checking availability of bpf_xdp_query_id and bpf_xdp_detach
and using them instead of deprecated APIs. Fall back to old
functions if not found.
- Dropped LIBBPF_LDADD variable as it makes library and function
detection much harder without providing any actual benefits.
AC_SEARCH_LIBS is used instead and it allows use of AC_CHECK_FUNCS.
- Header includes moved around to files where they are actually used.
- Removed libelf dependency as it is not really used.
With these changes it should be possible to build OVS with either:
- libbpf built from the kernel sources (5.19 or older).
- libbpf < 0.7 provided in distributions.
- libxdp and libbpf >= 0.7 provided in newer distributions.
While it is technically possible to build with libbpf 0.7+ without
libxdp at the moment we're not allowing that for a few reasons.
First, required functions in libbpf are deprecated and can be removed
in future releases. Second, support for all these combinations makes
the detection code fairly complex.
AFAIK, most of the distributions packaging libbpf 0.7+ do package
libxdp as well.
libxdp added as a build dependency for Fedora build since all
supported versions of Fedora are packaging this library.
Acked-by: Eelco Chaudron <echaudro@redhat.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | acinclude.m4 | 28 | ||||
-rw-r--r-- | lib/automake.mk | 1 | ||||
-rw-r--r-- | lib/libopenvswitch.pc.in | 2 | ||||
-rw-r--r-- | lib/netdev-afxdp-pool.c | 2 | ||||
-rw-r--r-- | lib/netdev-afxdp-pool.h | 5 | ||||
-rw-r--r-- | lib/netdev-afxdp.c | 38 | ||||
-rw-r--r-- | rhel/openvswitch-fedora.spec.in | 2 |
8 files changed, 53 insertions, 27 deletions
@@ -2,6 +2,8 @@ Post-v3.0.0 -------------------- - ovs-vswitchd now detects changes in CPU affinity and adjusts the number of handler and revalidator threads if necessary. + - AF_XDP: + * Added support for building with libxdp and libbpf >= 0.7. - ovs-appctl: * "ovs-appctl ofproto/trace" command can now display port names with the "--names" option. diff --git a/acinclude.m4 b/acinclude.m4 index aa9af5506..e47e925b3 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -251,7 +251,7 @@ AC_DEFUN([OVS_FIND_DEPENDENCY], [ dnl OVS_CHECK_LINUX_AF_XDP dnl -dnl Check both Linux kernel AF_XDP and libbpf support +dnl Check both Linux kernel AF_XDP and libbpf/libxdp support AC_DEFUN([OVS_CHECK_LINUX_AF_XDP], [ AC_ARG_ENABLE([afxdp], [AS_HELP_STRING([--enable-afxdp], [Enable AF-XDP support])], @@ -270,8 +270,21 @@ AC_DEFUN([OVS_CHECK_LINUX_AF_XDP], [ AC_CHECK_HEADER([linux/if_xdp.h], [], [AC_MSG_ERROR([unable to find linux/if_xdp.h for AF_XDP support])]) - AC_CHECK_HEADER([bpf/xsk.h], [], - [AC_MSG_ERROR([unable to find bpf/xsk.h for AF_XDP support])]) + OVS_FIND_DEPENDENCY([libbpf_strerror], [bpf], [libbpf]) + AC_CHECK_FUNCS([bpf_xdp_query_id bpf_xdp_detach]) + + if test "x$ac_cv_func_bpf_xdp_detach" = xyes; then + dnl We have libbpf >= 0.7. Look for libxdp as xsk functions + dnl were moved into this library. + OVS_FIND_DEPENDENCY([libxdp_strerror], [xdp], [libxdp]) + AC_CHECK_HEADER([xdp/xsk.h], + AC_DEFINE([HAVE_LIBXDP], [1], [xsk.h is supplied with libxdp]), + AC_MSG_ERROR([unable to find xdp/xsk.h for AF_XDP support])) + else + dnl libbpf < 0.7 contains all the necessary functionality. + AC_CHECK_HEADER([bpf/xsk.h], [], + [AC_MSG_ERROR([unable to find bpf/xsk.h for AF_XDP support])]) + fi AC_CHECK_FUNCS([pthread_spin_lock], [], [AC_MSG_ERROR([unable to find pthread_spin_lock for AF_XDP support])]) @@ -280,13 +293,6 @@ AC_DEFUN([OVS_CHECK_LINUX_AF_XDP], [ AC_DEFINE([HAVE_AF_XDP], [1], [Define to 1 if AF_XDP support is available and enabled.]) - LIBBPF_LDADD=" -lbpf -lelf" - AC_SUBST([LIBBPF_LDADD]) - - AC_CHECK_DECL([xsk_ring_prod__needs_wakeup], [ - AC_DEFINE([HAVE_XDP_NEED_WAKEUP], [1], - [XDP need wakeup support detected in xsk.h.]) - ], [], [[#include <bpf/xsk.h>]]) fi AM_CONDITIONAL([HAVE_AF_XDP], test "$AF_XDP_ENABLE" = true) ]) @@ -357,7 +363,7 @@ AC_DEFUN([OVS_CHECK_DPDK], [ ], [], [[#include <rte_config.h>]]) AC_CHECK_DECL([RTE_NET_AF_XDP], [ - LIBBPF_LDADD="-lbpf" + OVS_FIND_DEPENDENCY([libbpf_strerror], [bpf], [libbpf]) ], [], [[#include <rte_config.h>]]) AC_CHECK_DECL([RTE_LIBRTE_VHOST_NUMA], [ diff --git a/lib/automake.mk b/lib/automake.mk index a0fabe38f..61bdc308f 100644 --- a/lib/automake.mk +++ b/lib/automake.mk @@ -9,7 +9,6 @@ lib_LTLIBRARIES += lib/libopenvswitch.la lib_libopenvswitch_la_LIBADD = $(SSL_LIBS) lib_libopenvswitch_la_LIBADD += $(CAPNG_LDADD) -lib_libopenvswitch_la_LIBADD += $(LIBBPF_LDADD) if WIN32 diff --git a/lib/libopenvswitch.pc.in b/lib/libopenvswitch.pc.in index 44fbb1f9f..a5f4d3947 100644 --- a/lib/libopenvswitch.pc.in +++ b/lib/libopenvswitch.pc.in @@ -7,5 +7,5 @@ Name: libopenvswitch Description: Open vSwitch library Version: @VERSION@ Libs: -L${libdir} -lopenvswitch -Libs.private: @LIBS@ @SSL_LIBS@ @CAPNG_LDADD@ @LIBBPF_LDADD@ +Libs.private: @LIBS@ @SSL_LIBS@ @CAPNG_LDADD@ Cflags: -I${includedir} diff --git a/lib/netdev-afxdp-pool.c b/lib/netdev-afxdp-pool.c index 3386d2dcf..f56a7b29e 100644 --- a/lib/netdev-afxdp-pool.c +++ b/lib/netdev-afxdp-pool.c @@ -15,6 +15,8 @@ */ #include <config.h> +#include <errno.h> + #include "dp-packet.h" #include "netdev-afxdp-pool.h" #include "openvswitch/util.h" diff --git a/lib/netdev-afxdp-pool.h b/lib/netdev-afxdp-pool.h index f929b9489..6681cf539 100644 --- a/lib/netdev-afxdp-pool.h +++ b/lib/netdev-afxdp-pool.h @@ -19,12 +19,7 @@ #ifdef HAVE_AF_XDP -#include <bpf/xsk.h> -#include <errno.h> -#include <stdbool.h> - #include "openvswitch/thread.h" -#include "ovs-atomic.h" /* LIFO ptr_array. */ struct umem_pool { diff --git a/lib/netdev-afxdp.c b/lib/netdev-afxdp.c index 4d57efa5c..f8995da1f 100644 --- a/lib/netdev-afxdp.c +++ b/lib/netdev-afxdp.c @@ -21,6 +21,11 @@ #include "netdev-afxdp.h" #include "netdev-afxdp-pool.h" +#ifdef HAVE_LIBXDP +#include <xdp/xsk.h> +#else +#include <bpf/xsk.h> +#endif #include <errno.h> #include <inttypes.h> #include <linux/rtnetlink.h> @@ -29,6 +34,7 @@ #include <numa.h> #include <numaif.h> #include <poll.h> +#include <stdbool.h> #include <stdlib.h> #include <sys/resource.h> #include <sys/socket.h> @@ -44,6 +50,7 @@ #include "openvswitch/list.h" #include "openvswitch/thread.h" #include "openvswitch/vlog.h" +#include "ovs-atomic.h" #include "ovs-numa.h" #include "packets.h" #include "socket-util.h" @@ -72,7 +79,7 @@ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20); #define PROD_NUM_DESCS XSK_RING_PROD__DEFAULT_NUM_DESCS #define CONS_NUM_DESCS XSK_RING_CONS__DEFAULT_NUM_DESCS -#ifdef HAVE_XDP_NEED_WAKEUP +#ifdef XDP_USE_NEED_WAKEUP #define NEED_WAKEUP_DEFAULT true #else #define NEED_WAKEUP_DEFAULT false @@ -169,7 +176,7 @@ struct netdev_afxdp_tx_lock { ); }; -#ifdef HAVE_XDP_NEED_WAKEUP +#ifdef XDP_USE_NEED_WAKEUP static inline void xsk_rx_wakeup_if_needed(struct xsk_umem_info *umem, struct netdev *netdev, int fd) @@ -201,7 +208,7 @@ xsk_tx_need_wakeup(struct xsk_socket_info *xsk_info) return xsk_ring_prod__needs_wakeup(&xsk_info->tx); } -#else /* !HAVE_XDP_NEED_WAKEUP */ +#else /* !XDP_USE_NEED_WAKEUP */ static inline void xsk_rx_wakeup_if_needed(struct xsk_umem_info *umem OVS_UNUSED, struct netdev *netdev OVS_UNUSED, @@ -215,7 +222,7 @@ xsk_tx_need_wakeup(struct xsk_socket_info *xsk_info OVS_UNUSED) { return true; } -#endif /* HAVE_XDP_NEED_WAKEUP */ +#endif /* XDP_USE_NEED_WAKEUP */ static void netdev_afxdp_cleanup_unused_pool(struct unused_pool *pool) @@ -351,7 +358,7 @@ xsk_configure_socket(struct xsk_umem_info *umem, uint32_t ifindex, cfg.bind_flags = xdp_modes[mode].bind_flags; cfg.xdp_flags = xdp_modes[mode].xdp_flags | XDP_FLAGS_UPDATE_IF_NOEXIST; -#ifdef HAVE_XDP_NEED_WAKEUP +#ifdef XDP_USE_NEED_WAKEUP if (use_need_wakeup) { cfg.bind_flags |= XDP_USE_NEED_WAKEUP; } @@ -377,7 +384,11 @@ xsk_configure_socket(struct xsk_umem_info *umem, uint32_t ifindex, } /* Make sure the built-in AF_XDP program is loaded. */ +#ifdef HAVE_BPF_XDP_QUERY_ID + ret = bpf_xdp_query_id(ifindex, cfg.xdp_flags, &prog_id); +#else ret = bpf_get_link_xdp_id(ifindex, &prog_id, cfg.xdp_flags); +#endif if (ret || !prog_id) { if (ret) { VLOG_ERR("Get XDP prog ID failed (%s)", ovs_strerror(errno)); @@ -630,9 +641,9 @@ netdev_afxdp_set_config(struct netdev *netdev, const struct smap *args, } need_wakeup = smap_get_bool(args, "use-need-wakeup", NEED_WAKEUP_DEFAULT); -#ifndef HAVE_XDP_NEED_WAKEUP +#ifndef XDP_USE_NEED_WAKEUP if (need_wakeup) { - VLOG_WARN("XDP need_wakeup is not supported in libbpf."); + VLOG_WARN("XDP need_wakeup is not supported in libbpf/libxdp."); need_wakeup = false; } #endif @@ -742,7 +753,11 @@ xsk_remove_xdp_program(uint32_t ifindex, enum afxdp_mode mode) uint32_t ret, prog_id = 0; /* Check whether XDP program is loaded. */ +#ifdef HAVE_BPF_XDP_QUERY_ID + ret = bpf_xdp_query_id(ifindex, flags, &prog_id); +#else ret = bpf_get_link_xdp_id(ifindex, &prog_id, flags); +#endif if (ret) { VLOG_ERR("Failed to get XDP prog id (%s)", ovs_strerror(errno)); return; @@ -753,7 +768,14 @@ xsk_remove_xdp_program(uint32_t ifindex, enum afxdp_mode mode) return; } - bpf_set_link_xdp_fd(ifindex, -1, flags); +#ifdef HAVE_BPF_XDP_DETACH + if (bpf_xdp_detach(ifindex, flags, NULL) != 0) { +#else + if (bpf_set_link_xdp_fd(ifindex, -1, flags) != 0) { +#endif + VLOG_ERR("Failed to detach XDP program (%s) at ifindex %d", + ovs_strerror(errno), ifindex); + } } void diff --git a/rhel/openvswitch-fedora.spec.in b/rhel/openvswitch-fedora.spec.in index 8fc6e8ab2..eb5077a21 100644 --- a/rhel/openvswitch-fedora.spec.in +++ b/rhel/openvswitch-fedora.spec.in @@ -75,7 +75,7 @@ BuildRequires: dpdk-devel >= 22.11 Provides: %{name}-dpdk = %{version}-%{release} %endif %if %{with afxdp} -BuildRequires: libbpf-devel numactl-devel +BuildRequires: libxdp-devel libbpf-devel numactl-devel %endif BuildRequires: unbound unbound-devel |