diff --git a/drivers/net/tap/bpf/bpf_extract.py b/drivers/net/tap/bpf/bpf_extract.py
index b630c42b80..73c4dafe4e 100644
--- a/drivers/net/tap/bpf/bpf_extract.py
+++ b/drivers/net/tap/bpf/bpf_extract.py
@@ -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():
diff --git a/drivers/net/tap/meson.build b/drivers/net/tap/meson.build
index 5099ccdff1..66647a1c62 100644
--- a/drivers/net/tap/meson.build
+++ b/drivers/net/tap/meson.build
@@ -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=16'
@@ -23,12 +29,7 @@ cflags += '-DTAP_MAX_QUEUES=16'
 #   "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
diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
index 38a1b2d825..3f4fe95a09 100644
--- a/drivers/net/tap/rte_eth_tap.c
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -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)
diff --git a/drivers/net/tap/rte_eth_tap.h b/drivers/net/tap/rte_eth_tap.h
index 1bcf92ce80..af18b29090 100644
--- a/drivers/net/tap/rte_eth_tap.h
+++ b/drivers/net/tap/rte_eth_tap.h
@@ -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. */
diff --git a/drivers/net/tap/tap_bpf.h b/drivers/net/tap/tap_bpf.h
deleted file mode 100644
index d8437927ef..0000000000
--- a/drivers/net/tap/tap_bpf.h
+++ /dev/null
@@ -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 __rte_aligned(8) 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;
-	};
-};
-
-#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__ */
diff --git a/drivers/net/tap/tap_bpf_api.c b/drivers/net/tap/tap_bpf_api.c
index 15283f8917..9e05e2ddf1 100644
--- a/drivers/net/tap/tap_bpf_api.c
+++ b/drivers/net/tap/tap_bpf_api.c
@@ -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
 }
 
 /**
diff --git a/drivers/net/tap/tap_bpf_insns.h b/drivers/net/tap/tap_bpf_insns.h
index 53fa76c4e6..cdf2febf05 100644
--- a/drivers/net/tap/tap_bpf_insns.h
+++ b/drivers/net/tap/tap_bpf_insns.h
@@ -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},
diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
index 8cf64364a7..5a5a4ea048 100644
--- a/drivers/net/tap/tap_flow.c
+++ b/drivers/net/tap/tap_flow.c
@@ -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,
