Mirror the previous patch on the IPv6 side: report SKB_DROP_REASON_GRE_TUNNEL_NOT_FOUND when no tunnel matches the packet, and tell that apart from a header that cannot be pulled (SKB_DROP_REASON_HDR_TRUNC) or a metadata allocation failure (SKB_DROP_REASON_NOMEM), which so far all ended up in the same plain kfree_skb() in gre_rcv().
ip6gre_rcv() and ip6erspan_rcv() get the same output parameter as their IPv4 counterparts. Assisted-by: Claude-Code:claude-opus-5 Signed-off-by: Anton Danilov <[email protected]> --- net/ipv6/ip6_gre.c | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 736eefdb528f..27fbe175beec 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -454,7 +454,8 @@ static int ip6gre_err(struct sk_buff *skb, struct inet6_skb_parm *opt, return 0; } -static int ip6gre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi) +static int ip6gre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi, + enum skb_drop_reason *reason) { const struct ipv6hdr *ipv6h; struct ip6_tnl *tunnel; @@ -473,8 +474,10 @@ static int ip6gre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi) tun_id = key32_to_tunnel_id(tpi->key); tun_dst = ipv6_tun_rx_dst(skb, flags, tun_id, 0); - if (!tun_dst) + if (!tun_dst) { + *reason = SKB_DROP_REASON_NOMEM; return PACKET_REJECT; + } ip6_tnl_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error); } else { @@ -484,12 +487,14 @@ static int ip6gre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi) return PACKET_RCVD; } + *reason = SKB_DROP_REASON_GRE_TUNNEL_NOT_FOUND; return PACKET_REJECT; } static int ip6erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi, - int gre_hdr_len) + int gre_hdr_len, + enum skb_drop_reason *reason) { struct erspan_base_hdr *ershdr; const struct ipv6hdr *ipv6h; @@ -497,8 +502,10 @@ static int ip6erspan_rcv(struct sk_buff *skb, struct ip6_tnl *tunnel; u8 ver; - if (unlikely(!pskb_may_pull(skb, sizeof(*ershdr)))) + if (unlikely(!pskb_may_pull(skb, sizeof(*ershdr)))) { + *reason = SKB_DROP_REASON_HDR_TRUNC; return PACKET_REJECT; + } ipv6h = ipv6_hdr(skb); ershdr = (struct erspan_base_hdr *)skb->data; @@ -510,13 +517,17 @@ static int ip6erspan_rcv(struct sk_buff *skb, if (tunnel) { int len = erspan_hdr_len(ver); - if (unlikely(!pskb_may_pull(skb, len))) + if (unlikely(!pskb_may_pull(skb, len))) { + *reason = SKB_DROP_REASON_HDR_TRUNC; return PACKET_REJECT; + } if (__iptunnel_pull_header(skb, len, htons(ETH_P_TEB), - false, false) < 0) + false, false) < 0) { + *reason = SKB_DROP_REASON_HDR_TRUNC; return PACKET_REJECT; + } if (tunnel->parms.collect_md) { struct erspan_metadata *pkt_md, *md; @@ -532,8 +543,10 @@ static int ip6erspan_rcv(struct sk_buff *skb, tun_dst = ipv6_tun_rx_dst(skb, flags, tun_id, sizeof(*md)); - if (!tun_dst) + if (!tun_dst) { + *reason = SKB_DROP_REASON_NOMEM; return PACKET_REJECT; + } /* MUST set options_len before referencing options */ info = &tun_dst->u.tun_info; @@ -564,6 +577,7 @@ static int ip6erspan_rcv(struct sk_buff *skb, return PACKET_RCVD; } + *reason = SKB_DROP_REASON_GRE_TUNNEL_NOT_FOUND; return PACKET_REJECT; } @@ -577,17 +591,19 @@ static int gre_rcv(struct sk_buff *skb) if (hdr_len < 0) goto drop; - if (iptunnel_pull_header(skb, hdr_len, tpi.proto, false)) + if (iptunnel_pull_header(skb, hdr_len, tpi.proto, false)) { + reason = SKB_DROP_REASON_HDR_TRUNC; goto drop; + } if (unlikely(tpi.proto == htons(ETH_P_ERSPAN) || tpi.proto == htons(ETH_P_ERSPAN2))) { - if (ip6erspan_rcv(skb, &tpi, hdr_len) == PACKET_RCVD) + if (ip6erspan_rcv(skb, &tpi, hdr_len, &reason) == PACKET_RCVD) return 0; goto out; } - if (ip6gre_rcv(skb, &tpi) == PACKET_RCVD) + if (ip6gre_rcv(skb, &tpi, &reason) == PACKET_RCVD) return 0; out: -- 2.47.3

