summaryrefslogtreecommitdiff
path: root/drivers/net/geneve.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-07-24 16:21:27 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-07-24 16:21:27 +0200
commit8f9aa2c90530ab92301a82231ae44f3722becd93 (patch)
treefb282e955b0a880b07131a135257fe3ec764e928 /drivers/net/geneve.c
parent93467b31bec6da512b51544e5e4584f2745e995e (diff)
parent155b42bec9cbb6b8cdc47dd9bd09503a81fbe493 (diff)
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/net/geneve.c')
-rw-r--r--drivers/net/geneve.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
index 715180c3a1b3..c55bdb805a64 100644
--- a/drivers/net/geneve.c
+++ b/drivers/net/geneve.c
@@ -603,7 +603,7 @@ static int geneve_post_decap_hint(const struct sock *sk, struct sk_buff *skb,
ipv6h = (void *)skb->data + gro_hint->nested_nh_offset;
iph = (struct iphdr *)ipv6h;
total_len = skb->len - gro_hint->nested_nh_offset;
- if (total_len > GRO_LEGACY_MAX_SIZE)
+ if (total_len >= GRO_LEGACY_MAX_SIZE)
return -E2BIG;
/*
@@ -948,13 +948,27 @@ static int geneve_gro_complete(struct sock *sk, struct sk_buff *skb,
struct genevehdr *gh;
struct packet_offload *ptype;
__be16 type;
- int gh_len;
+ unsigned int gh_len;
int err = -ENOSYS;
gh = (struct genevehdr *)(skb->data + nhoff);
gh_len = geneve_hlen(gh);
type = gh->proto_type;
- geneve_opt_gro_hint_off(gh, &type, &gh_len);
+ geneve_sk_gro_hint_off(sk, gh, &type, &gh_len);
+
+ /* Bail out if we are about to dispatch past the inner network header
+ * gro_receive() validated. An inner VLAN tag only pushes
+ * inner_network_offset out, so use a lower bound.
+ */
+ if (skb->encapsulation) {
+ unsigned int inner_nh = nhoff + gh_len;
+
+ if (type == htons(ETH_P_TEB))
+ inner_nh += ETH_HLEN;
+
+ if (unlikely(inner_nh > NAPI_GRO_CB(skb)->inner_network_offset))
+ return -EINVAL;
+ }
/* since skb->encapsulation is set, eth_gro_complete() sets the inner mac header */
if (likely(type == htons(ETH_P_TEB)))
@@ -1006,7 +1020,7 @@ static struct geneve_sock *geneve_socket_create(struct net *net, __be16 port,
tunnel_cfg.encap_rcv = geneve_udp_encap_recv;
tunnel_cfg.encap_err_lookup = geneve_udp_encap_err_lookup;
tunnel_cfg.encap_destroy = NULL;
- setup_udp_tunnel_sock(net, sock, &tunnel_cfg);
+ setup_udp_tunnel_sock(net, sock->sk, &tunnel_cfg);
list_add(&gs->list, &gn->sock_list);
return gs;
}
@@ -1018,7 +1032,7 @@ static void __geneve_sock_release(struct geneve_sock *gs)
list_del(&gs->list);
udp_tunnel_notify_del_rx_port(gs->sock, UDP_TUNNEL_TYPE_GENEVE);
- udp_tunnel_sock_release(gs->sock);
+ udp_tunnel_sock_release(gs->sock->sk);
kfree_rcu(gs, rcu);
}