@@ -65,7 +65,6 @@ def write_header(out, source):
print(f' * Auto-generated from {source}', file=out)
print(" * This not the original source file. Do NOT edit it.", file=out)
print(" */\n", file=out)
- print("#include <tap_bpf.h>", file=out)
def main():
@@ -7,13 +7,19 @@ if not is_linux
endif
sources = files(
'rte_eth_tap.c',
- 'tap_bpf_api.c',
- 'tap_flow.c',
'tap_intr.c',
'tap_netlink.c',
- 'tap_tcmsgs.c',
)
+if cc.has_header_symbol('linux/pkt_cls.h', 'TCA_FLOWER_ACT')
+ cflags += '-DHAVE_TCA_FLOWER'
+ sources += files(
+ 'tap_bpf_api.c',
+ 'tap_flow.c',
+ 'tap_tcmsgs.c',
+ )
+endif
+
deps = ['bus_vdev', 'gso', 'hash']
cflags += '-DTAP_MAX_QUEUES=8'
@@ -23,12 +29,7 @@ cflags += '-DTAP_MAX_QUEUES=8'
# "enum/define", "symbol to search" ]
#
args = [
- [ 'HAVE_TC_FLOWER', 'linux/pkt_cls.h', 'TCA_FLOWER_UNSPEC' ],
- [ 'HAVE_TC_VLAN_ID', 'linux/pkt_cls.h', 'TCA_FLOWER_KEY_VLAN_PRIO' ],
- [ 'HAVE_TC_BPF', 'linux/pkt_cls.h', 'TCA_BPF_UNSPEC' ],
- [ 'HAVE_TC_BPF_FD', 'linux/pkt_cls.h', 'TCA_BPF_FD' ],
[ 'HAVE_TC_ACT_BPF', 'linux/tc_act/tc_bpf.h', 'TCA_ACT_BPF_UNSPEC' ],
- [ 'HAVE_TC_ACT_BPF_FD', 'linux/tc_act/tc_bpf.h', 'TCA_ACT_BPF_FD' ],
]
config = configuration_data()
foreach arg:args
@@ -1124,12 +1124,15 @@ tap_dev_close(struct rte_eth_dev *dev)
if (!internals->persist)
tap_link_set_down(dev);
+
+#ifdef HAVE_TCA_FLOWER
if (internals->nlsk_fd != -1) {
tap_flow_flush(dev, NULL);
tap_flow_implicit_flush(internals, NULL);
tap_nl_final(internals->nlsk_fd);
internals->nlsk_fd = -1;
}
+#endif
for (i = 0; i < RTE_PMD_TAP_MAX_QUEUES; i++) {
struct rx_queue *rxq = &internals->rxq[i];
@@ -1265,6 +1268,7 @@ tap_promisc_enable(struct rte_eth_dev *dev)
if (ret != 0)
return ret;
+#ifdef HAVE_TCA_FLOWER
if (pmd->remote_if_index && !pmd->flow_isolate) {
dev->data->promiscuous = 1;
ret = tap_flow_implicit_create(pmd, TAP_REMOTE_PROMISC);
@@ -1278,7 +1282,7 @@ tap_promisc_enable(struct rte_eth_dev *dev)
return ret;
}
}
-
+#endif
return 0;
}
@@ -1293,6 +1297,7 @@ tap_promisc_disable(struct rte_eth_dev *dev)
if (ret != 0)
return ret;
+#ifdef HAVE_TCA_FLOWER
if (pmd->remote_if_index && !pmd->flow_isolate) {
dev->data->promiscuous = 0;
ret = tap_flow_implicit_destroy(pmd, TAP_REMOTE_PROMISC);
@@ -1306,6 +1311,7 @@ tap_promisc_disable(struct rte_eth_dev *dev)
return ret;
}
}
+#endif
return 0;
}
@@ -1321,6 +1327,7 @@ tap_allmulti_enable(struct rte_eth_dev *dev)
if (ret != 0)
return ret;
+#ifdef HAVE_TCA_FLOWER
if (pmd->remote_if_index && !pmd->flow_isolate) {
dev->data->all_multicast = 1;
ret = tap_flow_implicit_create(pmd, TAP_REMOTE_ALLMULTI);
@@ -1334,6 +1341,7 @@ tap_allmulti_enable(struct rte_eth_dev *dev)
return ret;
}
}
+#endif
return 0;
}
@@ -1349,6 +1357,7 @@ tap_allmulti_disable(struct rte_eth_dev *dev)
if (ret != 0)
return ret;
+#ifdef HAVE_TCA_FLOWER
if (pmd->remote_if_index && !pmd->flow_isolate) {
dev->data->all_multicast = 0;
ret = tap_flow_implicit_destroy(pmd, TAP_REMOTE_ALLMULTI);
@@ -1362,6 +1371,7 @@ tap_allmulti_disable(struct rte_eth_dev *dev)
return ret;
}
}
+#endif
return 0;
}
@@ -1407,6 +1417,8 @@ tap_mac_set(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr)
if (ret < 0)
return ret;
rte_memcpy(&pmd->eth_addr, mac_addr, RTE_ETHER_ADDR_LEN);
+
+#ifdef HAVE_TCA_FLOWER
if (pmd->remote_if_index && !pmd->flow_isolate) {
/* Replace MAC redirection rule after a MAC change */
ret = tap_flow_implicit_destroy(pmd, TAP_REMOTE_LOCAL_MAC);
@@ -1424,6 +1436,7 @@ tap_mac_set(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr)
return ret;
}
}
+#endif
return 0;
}
@@ -1901,7 +1914,9 @@ static const struct eth_dev_ops ops = {
.stats_reset = tap_stats_reset,
.dev_supported_ptypes_get = tap_dev_supported_ptypes_get,
.rss_hash_update = tap_rss_hash_update,
+#ifdef HAVE_TCA_FLOWER
.flow_ops_get = tap_dev_flow_ops_get,
+#endif
};
static int
@@ -1941,7 +1956,9 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name,
strlcpy(pmd->name, tap_name, sizeof(pmd->name));
pmd->type = type;
pmd->ka_fd = -1;
+#ifdef HAVE_TCA_FLOWER
pmd->nlsk_fd = -1;
+#endif
pmd->gso_ctx_mp = NULL;
pmd->ioctl_sock = socket(AF_INET, SOCK_DGRAM, 0);
@@ -2021,6 +2038,14 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name,
/* Make network device persist after application exit */
pmd->persist = persist;
+ pmd->if_index = if_nametoindex(pmd->name);
+ if (!pmd->if_index) {
+ TAP_LOG(ERR, "%s: failed to get if_index.", pmd->name);
+ goto disable_rte_flow;
+ }
+
+
+#ifdef HAVE_TCA_FLOWER
/*
* Set up everything related to rte_flow:
* - netlink socket
@@ -2035,11 +2060,6 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name,
pmd->name);
goto disable_rte_flow;
}
- pmd->if_index = if_nametoindex(pmd->name);
- if (!pmd->if_index) {
- TAP_LOG(ERR, "%s: failed to get if_index.", pmd->name);
- goto disable_rte_flow;
- }
if (qdisc_create_multiq(pmd->nlsk_fd, pmd->if_index) < 0) {
TAP_LOG(ERR, "%s: failed to create multiq qdisc.",
pmd->name);
@@ -2050,6 +2070,7 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name,
pmd->name);
goto disable_rte_flow;
}
+
LIST_INIT(&pmd->flows);
if (strlen(remote_iface)) {
@@ -2102,6 +2123,7 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name,
goto error_remote;
}
}
+#endif
rte_eth_dev_probing_finish(dev);
return 0;
@@ -2116,14 +2138,18 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name,
rte_eth_dev_probing_finish(dev);
return 0;
+#ifdef HAVE_TCA_FLOWER
error_remote:
TAP_LOG(ERR, " Can't set up remote feature: %s(%d)",
strerror(errno), errno);
tap_flow_implicit_flush(pmd, NULL);
+#endif
error_exit:
+#ifdef HAVE_TCA_FLOWER
if (pmd->nlsk_fd != -1)
close(pmd->nlsk_fd);
+#endif
if (pmd->ka_fd != -1)
close(pmd->ka_fd);
if (pmd->ioctl_sock != -1)
@@ -16,6 +16,7 @@
#include <ethdev_driver.h>
#include <rte_ether.h>
#include <rte_gso.h>
+
#include "tap_log.h"
#ifdef IFF_MULTI_QUEUE
@@ -70,15 +71,17 @@ struct pmd_internals {
char remote_iface[RTE_ETH_NAME_MAX_LEN]; /* Remote netdevice name */
char name[RTE_ETH_NAME_MAX_LEN]; /* Internal Tap device name */
int type; /* Type field - TUN|TAP */
+ int persist; /* 1 if keep link up, else 0 */
struct rte_ether_addr eth_addr; /* Mac address of the device port */
struct ifreq remote_initial_flags;/* Remote netdevice flags on init */
int remote_if_index; /* remote netdevice IF_INDEX */
int if_index; /* IF_INDEX for the port */
int ioctl_sock; /* socket for ioctl calls */
+
+#ifdef HAVE_TCA_FLOWER
int nlsk_fd; /* Netlink socket fd */
int flow_isolate; /* 1 if flow isolation is enabled */
int rss_enabled; /* 1 if RSS is enabled, else 0 */
- int persist; /* 1 if keep link up, else 0 */
/* implicit rules set when RSS is enabled */
int map_fd; /* BPF RSS map fd */
int bpf_fd[RTE_PMD_TAP_MAX_QUEUES];/* List of bpf fds per queue */
@@ -86,6 +89,8 @@ struct pmd_internals {
LIST_HEAD(tap_flows, rte_flow) flows; /* rte_flow rules */
/* implicit rte_flow rules set when a remote device is active */
LIST_HEAD(tap_implicit_flows, rte_flow) implicit_flows;
+#endif
+
struct rx_queue rxq[RTE_PMD_TAP_MAX_QUEUES]; /* List of RX queues */
struct tx_queue txq[RTE_PMD_TAP_MAX_QUEUES]; /* List of TX queues */
struct rte_intr_handle *intr_handle; /* LSC interrupt handle. */
deleted file mode 100644
@@ -1,121 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
- * Copyright 2017 Mellanox Technologies, Ltd
- */
-
-#ifndef __TAP_BPF_H__
-#define __TAP_BPF_H__
-
-#include <tap_autoconf.h>
-
-/* Do not #include <linux/bpf.h> since eBPF must compile on different
- * distros which may include partial definitions for eBPF (while the
- * kernel itself may support eBPF). Instead define here all that is needed
- */
-
-/* BPF_MAP_UPDATE_ELEM command flags */
-#define BPF_ANY 0 /* create a new element or update an existing */
-
-/* BPF architecture instruction struct */
-struct bpf_insn {
- __u8 code;
- __u8 dst_reg:4;
- __u8 src_reg:4;
- __s16 off;
- __s32 imm; /* immediate value */
-};
-
-/* BPF program types */
-enum bpf_prog_type {
- BPF_PROG_TYPE_UNSPEC,
- BPF_PROG_TYPE_SOCKET_FILTER,
- BPF_PROG_TYPE_KPROBE,
- BPF_PROG_TYPE_SCHED_CLS,
- BPF_PROG_TYPE_SCHED_ACT,
-};
-
-/* BPF commands types */
-enum bpf_cmd {
- BPF_MAP_CREATE,
- BPF_MAP_LOOKUP_ELEM,
- BPF_MAP_UPDATE_ELEM,
- BPF_MAP_DELETE_ELEM,
- BPF_MAP_GET_NEXT_KEY,
- BPF_PROG_LOAD,
-};
-
-/* BPF maps types */
-enum bpf_map_type {
- BPF_MAP_TYPE_UNSPEC,
- BPF_MAP_TYPE_HASH,
-};
-
-/* union of anonymous structs used with TAP BPF commands */
-union bpf_attr {
- /* BPF_MAP_CREATE command */
- struct {
- __u32 map_type;
- __u32 key_size;
- __u32 value_size;
- __u32 max_entries;
- __u32 map_flags;
- __u32 inner_map_fd;
- };
-
- /* BPF_MAP_UPDATE_ELEM, BPF_MAP_DELETE_ELEM commands */
- struct {
- __u32 map_fd;
- __aligned_u64 key;
- union {
- __aligned_u64 value;
- __aligned_u64 next_key;
- };
- __u64 flags;
- };
-
- /* BPF_PROG_LOAD command */
- struct {
- __u32 prog_type;
- __u32 insn_cnt;
- __aligned_u64 insns;
- __aligned_u64 license;
- __u32 log_level;
- __u32 log_size;
- __aligned_u64 log_buf;
- __u32 kern_version;
- __u32 prog_flags;
- };
-} __rte_aligned(8);
-
-#ifndef __NR_bpf
-# if defined(__i386__)
-# define __NR_bpf 357
-# elif defined(__x86_64__)
-# define __NR_bpf 321
-# elif defined(__arm__)
-# define __NR_bpf 386
-# elif defined(__aarch64__)
-# define __NR_bpf 280
-# elif defined(__sparc__)
-# define __NR_bpf 349
-# elif defined(__s390__)
-# define __NR_bpf 351
-# elif defined(__powerpc__)
-# define __NR_bpf 361
-# elif defined(__riscv)
-# define __NR_bpf 280
-# elif defined(__loongarch__)
-# define __NR_bpf 280
-# else
-# error __NR_bpf not defined
-# endif
-#endif
-
-enum {
- BPF_MAP_ID_KEY,
- BPF_MAP_ID_SIMPLE,
-};
-
-static int bpf_load(enum bpf_prog_type type, const struct bpf_insn *insns,
- size_t insns_cnt, const char *license);
-
-#endif /* __TAP_BPF_H__ */
@@ -2,19 +2,19 @@
* Copyright 2017 Mellanox Technologies, Ltd
*/
-#include <errno.h>
-#include <string.h>
#include <unistd.h>
-#include <sys/queue.h>
+#include <syscall.h>
+#include <linux/bpf.h>
-#include <rte_malloc.h>
-#include <rte_eth_tap.h>
#include <tap_flow.h>
#include <tap_autoconf.h>
-#include <tap_tcmsgs.h>
-#include <tap_bpf.h>
+
#include <tap_bpf_insns.h>
+
+static int bpf_load(enum bpf_prog_type type, const struct bpf_insn *insns,
+ size_t insns_cnt, const char *license);
+
/**
* Load BPF program (section cls_q) into the kernel and return a bpf fd
*
@@ -89,7 +89,13 @@ static inline __u64 ptr_to_u64(const void *ptr)
static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr,
unsigned int size)
{
+#ifdef __NR_bpf
return syscall(__NR_bpf, cmd, attr, size);
+#else
+ TAP_LOG(ERR, "No bpf syscall, kernel headers too old?\n");
+ errno = ENOSYS;
+ return -1;
+#endif
}
/**
@@ -3,8 +3,6 @@
* This not the original source file. Do NOT edit it.
*/
-#include <tap_bpf.h>
-
static struct bpf_insn cls_q_insns[] = {
{0x61, 2, 1, 52, 0x00000000},
{0x18, 3, 0, 0, 0xdeadbeef},
@@ -21,96 +21,6 @@
#include <tap_tcmsgs.h>
#include <tap_rss.h>
-#ifndef HAVE_TC_FLOWER
-/*
- * For kernels < 4.2, this enum is not defined. Runtime checks will be made to
- * avoid sending TC messages the kernel cannot understand.
- */
-enum {
- TCA_FLOWER_UNSPEC,
- TCA_FLOWER_CLASSID,
- TCA_FLOWER_INDEV,
- TCA_FLOWER_ACT,
- TCA_FLOWER_KEY_ETH_DST, /* ETH_ALEN */
- TCA_FLOWER_KEY_ETH_DST_MASK, /* ETH_ALEN */
- TCA_FLOWER_KEY_ETH_SRC, /* ETH_ALEN */
- TCA_FLOWER_KEY_ETH_SRC_MASK, /* ETH_ALEN */
- TCA_FLOWER_KEY_ETH_TYPE, /* be16 */
- TCA_FLOWER_KEY_IP_PROTO, /* u8 */
- TCA_FLOWER_KEY_IPV4_SRC, /* be32 */
- TCA_FLOWER_KEY_IPV4_SRC_MASK, /* be32 */
- TCA_FLOWER_KEY_IPV4_DST, /* be32 */
- TCA_FLOWER_KEY_IPV4_DST_MASK, /* be32 */
- TCA_FLOWER_KEY_IPV6_SRC, /* struct in6_addr */
- TCA_FLOWER_KEY_IPV6_SRC_MASK, /* struct in6_addr */
- TCA_FLOWER_KEY_IPV6_DST, /* struct in6_addr */
- TCA_FLOWER_KEY_IPV6_DST_MASK, /* struct in6_addr */
- TCA_FLOWER_KEY_TCP_SRC, /* be16 */
- TCA_FLOWER_KEY_TCP_DST, /* be16 */
- TCA_FLOWER_KEY_UDP_SRC, /* be16 */
- TCA_FLOWER_KEY_UDP_DST, /* be16 */
-};
-#endif
-#ifndef HAVE_TC_VLAN_ID
-enum {
- /* TCA_FLOWER_FLAGS, */
- TCA_FLOWER_KEY_VLAN_ID = TCA_FLOWER_KEY_UDP_DST + 2, /* be16 */
- TCA_FLOWER_KEY_VLAN_PRIO, /* u8 */
- TCA_FLOWER_KEY_VLAN_ETH_TYPE, /* be16 */
-};
-#endif
-/*
- * For kernels < 4.2 BPF related enums may not be defined.
- * Runtime checks will be carried out to gracefully report on TC messages that
- * are rejected by the kernel. Rejection reasons may be due to:
- * 1. enum is not defined
- * 2. enum is defined but kernel is not configured to support BPF system calls,
- * BPF classifications or BPF actions.
- */
-#ifndef HAVE_TC_BPF
-enum {
- TCA_BPF_UNSPEC,
- TCA_BPF_ACT,
- TCA_BPF_POLICE,
- TCA_BPF_CLASSID,
- TCA_BPF_OPS_LEN,
- TCA_BPF_OPS,
-};
-#endif
-#ifndef HAVE_TC_BPF_FD
-enum {
- TCA_BPF_FD = TCA_BPF_OPS + 1,
- TCA_BPF_NAME,
-};
-#endif
-#ifndef HAVE_TC_ACT_BPF
-#define tc_gen \
- __u32 index; \
- __u32 capab; \
- int action; \
- int refcnt; \
- int bindcnt
-
-struct tc_act_bpf {
- tc_gen;
-};
-
-enum {
- TCA_ACT_BPF_UNSPEC,
- TCA_ACT_BPF_TM,
- TCA_ACT_BPF_PARMS,
- TCA_ACT_BPF_OPS_LEN,
- TCA_ACT_BPF_OPS,
-};
-
-#endif
-#ifndef HAVE_TC_ACT_BPF_FD
-enum {
- TCA_ACT_BPF_FD = TCA_ACT_BPF_OPS + 1,
- TCA_ACT_BPF_NAME,
-};
-#endif
-
/* RSS key management */
enum bpf_rss_key_e {
KEY_CMD_GET = 1,