]> git.ipfire.org Git - thirdparty/knot-dns.git/commitdiff
xdp: add XDP mode detection via knot_eth_xdp_mode()
authorDaniel Salzman <daniel.salzman@nic.cz>
Tue, 3 Nov 2020 12:41:57 +0000 (13:41 +0100)
committerDaniel Salzman <daniel.salzman@nic.cz>
Tue, 3 Nov 2020 14:13:32 +0000 (15:13 +0100)
distro/deb/libknot11.symbols
src/libknot/xdp/eth.c
src/libknot/xdp/eth.h

index 90964e39085d9f1af1a2753f7d24bd51837aaff3..6df77119b5140df6e39161529b887258ec9042fe 100644 (file)
@@ -80,6 +80,7 @@ libknot.so.11 libknot11 #MINVER#
  knot_error_from_libdnssec@Base 3.0.0
  knot_eth_name_from_addr@Base 3.0.0
  knot_eth_queues@Base 3.0.0
+ knot_eth_xdp_mode@Base 3.0.2
  knot_get_obsolete_rdata_descriptor@Base 3.0.0
  knot_get_rdata_descriptor@Base 3.0.0
  knot_naptr_header_size@Base 3.0.0
index d5d1d2ae556979ec5b0de16f511a4c894cc411fb..b3614b6e2c68b02a3c144984f7b93c64db5fc261 100644 (file)
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
+#include <bpf/libbpf.h>
 #include <errno.h>
 #include <ifaddrs.h>
 #include <linux/ethtool.h>
 #include <linux/if.h>
+#include <linux/if_link.h>
 #include <linux/sockios.h>
 #include <sys/ioctl.h>
 #include <unistd.h>
@@ -105,3 +107,23 @@ int knot_eth_name_from_addr(const struct sockaddr_storage *addr, char *out,
        freeifaddrs(ifaces);
        return matches == 0 ? KNOT_EADDRNOTAVAIL : KNOT_ELIMIT;
 }
+
+_public_
+knot_xdp_mode_t knot_eth_xdp_mode(int if_index)
+{
+       struct xdp_link_info info;
+       int ret = bpf_get_link_xdp_info(if_index, &info, sizeof(info), 0);
+       if (ret != 0) {
+               return KNOT_XDP_MODE_NONE;
+       }
+
+       switch (info.attach_mode) {
+       case XDP_ATTACHED_DRV:
+       case XDP_ATTACHED_HW:
+               return KNOT_XDP_MODE_FULL;
+       case XDP_ATTACHED_SKB:
+               return KNOT_XDP_MODE_EMUL;
+       default:
+               return KNOT_XDP_MODE_NONE;
+       }
+}
index b5fc7ff259859ea4653b7a12593c8639cffcfadd..eb196e19b223858b5c7a47aa72dfc75fb94c2edf 100644 (file)
@@ -40,3 +40,18 @@ int knot_eth_queues(const char *devname);
  */
 int knot_eth_name_from_addr(const struct sockaddr_storage *addr, char *out,
                             size_t out_len);
+
+typedef enum {
+       KNOT_XDP_MODE_NONE, /*!< XDP not available or error. */
+       KNOT_XDP_MODE_FULL, /*!< Full XDP support in driver or HW. */
+       KNOT_XDP_MODE_EMUL, /*!< Emulated XDP support. */
+} knot_xdp_mode_t;
+
+/*!
+ * \brief Check if the network inteface supports XDP.
+ *
+ * \param if_index  Index of interface, output from if_nametoindex().
+ *
+ * \return Supported XDP mode.
+ */
+knot_xdp_mode_t knot_eth_xdp_mode(int if_index);