summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2026-08-06 23:09:06 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2026-08-10 13:02:28 +0200
commit5592223f3d4e45fb5e98ea7fe9be075725f40ff7 (patch)
tree941e2b393c38d54bd1611d3cd3f78155c4494fae
parent95133a416809c7e822da4023b7f4193ef2620796 (diff)
net: netfilter: add ether_type to net_device_path_ctx and use it
Add an ether_type field to struct net_device_path_ctx to reject IPv4 over IPv6 and vice-versa, this is currently not support. Otherwise, incorrect dst_entry family can be reached from datapath. Acked-by: Lorenzo Bianconi <lorenzo@kernel.org> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--include/linux/netdevice.h1
-rw-r--r--net/ipv4/ipip.c3
-rw-r--r--net/ipv6/ip6_tunnel.c3
-rw-r--r--net/netfilter/nf_flow_table_path.c6
4 files changed, 11 insertions, 2 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 17d28adb029b..2327a2703b83 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -941,6 +941,7 @@ struct net_device_path_stack {
struct net_device_path_ctx {
const struct net_device *dev;
u8 daddr[ETH_ALEN];
+ __be16 ether_type;
int num_vlans;
struct {
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index fb7d96f99b06..62a374079bfc 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -360,6 +360,9 @@ static int ipip_fill_forward_path(struct net_device_path_ctx *ctx,
const struct iphdr *tiph = &tunnel->parms.iph;
struct rtable *rt;
+ if (ctx->ether_type != cpu_to_be16(ETH_P_IP))
+ return -EOPNOTSUPP;
+
if (tunnel->collect_md)
return -EOPNOTSUPP;
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 042d743edb6c..d063add01f52 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1852,6 +1852,9 @@ static int ip6_tnl_fill_forward_path(struct net_device_path_ctx *ctx,
struct flowi6 fl6;
int err;
+ if (ctx->ether_type != cpu_to_be16(ETH_P_IPV6))
+ return -EOPNOTSUPP;
+
if (t->parms.flags & (IP6_TNL_F_USE_ORIG_TCLASS |
IP6_TNL_F_USE_ORIG_FLOWLABEL |
IP6_TNL_F_USE_ORIG_FWMARK))
diff --git a/net/netfilter/nf_flow_table_path.c b/net/netfilter/nf_flow_table_path.c
index 0cbde535b8ba..5f166da3b09b 100644
--- a/net/netfilter/nf_flow_table_path.c
+++ b/net/netfilter/nf_flow_table_path.c
@@ -44,13 +44,15 @@ static bool nft_is_valid_ether_device(const struct net_device *dev)
static int nft_dev_fill_forward_path(const struct dst_entry *dst_cache,
const struct nf_conn *ct,
- enum ip_conntrack_dir dir, u8 *ha,
+ enum ip_conntrack_dir dir,
+ u8 *ha, __be16 ether_type,
struct net_device_path_stack *stack)
{
const void *daddr = &ct->tuplehash[!dir].tuple.src.u3;
struct net_device *dev = dst_cache->dev;
struct net_device_path_ctx ctx = {
.dev = dev,
+ .ether_type = ether_type,
};
struct neighbour *n;
u8 nud_state;
@@ -228,7 +230,7 @@ static int nft_dev_forward_path(const struct nft_pktinfo *pkt,
unsigned char ha[ETH_ALEN];
int i;
- if (nft_dev_fill_forward_path(dst, ct, dir, ha, &stack) < 0 ||
+ if (nft_dev_fill_forward_path(dst, ct, dir, ha, pkt->ethertype, &stack) < 0 ||
nft_dev_path_info(&stack, &info, ha, ft) < 0)
return -ENOENT;