From: Anton Danilov <littlesmilingcloud@gmail.com>
To: netdev@vger.kernel.org
Cc: "David S . Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
David Ahern <dsahern@kernel.org>, Simon Horman <horms@kernel.org>,
Ido Schimmel <idosch@nvidia.com>,
linux-kernel@vger.kernel.org
Subject: [PATCH net-next v4 01/10] ip_tunnel: add drop reasons to the generic RX path
Date: Wed, 23 Sep 2026 01:14:58 +0300 [thread overview]
Message-ID: <20260922221507.3268127-2-littlesmilingcloud@gmail.com> (raw)
In-Reply-To: <20260922221507.3268127-1-littlesmilingcloud@gmail.com>
ip_tunnel_rcv() collapses four distinct failures into the single
kfree_skb() under its drop label:
- the tunnel options carried by the packet do not match the tunnel
configuration (checksum or sequence number),
- the sequence number is older than the expected one,
- the inner network header cannot be pulled,
- the ECN decapsulation check fails (RFC 6040).
drop_monitor and the skb:kfree_skb tracepoint do see these packets, but
all four as SKB_DROP_REASON_NOT_SPECIFIED from the same call site, so
neither the reason nor the location tells the failures apart. Only the
device error counters (rx_crc_errors, rx_fifo_errors, rx_length_errors,
rx_frame_errors) hint at the cause, and they are not tied to the
dropped packet.
Add two drop reasons for the tunnel specific cases and reuse the
existing ones for the rest:
- SKB_DROP_REASON_TNL_OPT_MISMATCH is used when the packet lacks the
checksum or the sequence number option the tunnel is configured for,
or carries a checksum the tunnel is not configured for, as the
checksum check compares both ways. This is a configuration mismatch
between the two endpoints rather than a corrupted checksum: the
checksum itself is validated earlier, in gre_parse_header().
- SKB_DROP_REASON_TNL_OLD_SEQ is used when the sequence number is older
than the expected one. Unlike the previous one, this is a property
of the received traffic: a remote endpoint that restarts and resets
its sequence numbering has all of its packets dropped until its
sequence numbers catch up with i_seqno.
- pskb_inet_may_pull_reason() already computes a drop reason,
SKB_DROP_REASON_PKT_TOO_SMALL or SKB_DROP_REASON_NOMEM, which has so
far been discarded.
- SKB_DROP_REASON_IP_TUNNEL_ECN already exists and documents exactly
this check, but until now it was only used by vxlan.
The sequence number check is split in two so that the two cases can be
told apart. The error counters are left unchanged.
ip_tunnel_rcv() is the RX path of ip_gre, ipip and sit, the latter for
IPv4 and MPLS payloads only: ipip6_rcv() handles IPv6 in IPv4 on its
own. The checksum and the sequence number options only exist for GRE,
so the two new reasons are meant for ip_gre. ipip and sit carry
neither option and only hit SKB_DROP_REASON_TNL_OPT_MISMATCH if their
i_flags are given those bits, for instance through IFLA_IPTUN_FLAGS;
such a device then drops every packet that reaches ip_tunnel_rcv(),
with or without this patch. The ECN reason applies to all three, while
the length ones can only be hit through ip_gre: tunnel4_rcv() has
already pulled the inner IPv4 header for ipip and sit, and
pskb_inet_may_pull_reason() has nothing to pull for an MPLS payload.
Assisted-by: Claude-Code:claude-opus-5
Signed-off-by: Anton Danilov <littlesmilingcloud@gmail.com>
---
include/net/dropreason-core.h | 17 +++++++++++++++++
net/ipv4/ip_tunnel.c | 19 +++++++++++++++----
2 files changed, 32 insertions(+), 4 deletions(-)
diff --git a/include/net/dropreason-core.h b/include/net/dropreason-core.h
index 12f909651591..edbe58a22ddf 100644
--- a/include/net/dropreason-core.h
+++ b/include/net/dropreason-core.h
@@ -129,6 +129,8 @@
FN(PSP_INPUT) \
FN(PSP_OUTPUT) \
FN(RECURSION_LIMIT) \
+ FN(TNL_OPT_MISMATCH) \
+ FN(TNL_OLD_SEQ) \
FNe(MAX)
/**
@@ -612,6 +614,21 @@ enum skb_drop_reason {
SKB_DROP_REASON_PSP_OUTPUT,
/** @SKB_DROP_REASON_RECURSION_LIMIT: Dead loop on virtual device. */
SKB_DROP_REASON_RECURSION_LIMIT,
+ /**
+ * @SKB_DROP_REASON_TNL_OPT_MISMATCH: the tunnel options
+ * carried by the packet do not match the tunnel configuration, e.g.
+ * a GRE tunnel configured with 'icsum' or 'iseq' received a packet
+ * with no checksum or no sequence number, or a GRE tunnel without
+ * 'icsum' received a packet with a checksum.
+ */
+ SKB_DROP_REASON_TNL_OPT_MISMATCH,
+ /**
+ * @SKB_DROP_REASON_TNL_OLD_SEQ: the sequence number carried
+ * by the packet is older than the one expected by the tunnel, e.g.
+ * after the remote endpoint restarted and reset its sequence
+ * numbering.
+ */
+ SKB_DROP_REASON_TNL_OLD_SEQ,
/**
* @SKB_DROP_REASON_MAX: the maximum of core drop reasons, which
* shouldn't be used as a real 'reason' - only for tracing code gen
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index 0875474a578a..c94f4c055027 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -384,6 +384,7 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
const struct tnl_ptk_info *tpi, struct metadata_dst *tun_dst,
bool log_ecn_error)
{
+ enum skb_drop_reason reason = SKB_DROP_REASON_NOT_SPECIFIED;
const struct iphdr *iph = ip_hdr(skb);
int nh, err;
@@ -398,14 +399,22 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
test_bit(IP_TUNNEL_CSUM_BIT, tpi->flags)) {
DEV_STATS_INC(tunnel->dev, rx_crc_errors);
DEV_STATS_INC(tunnel->dev, rx_errors);
+ reason = SKB_DROP_REASON_TNL_OPT_MISMATCH;
goto drop;
}
if (test_bit(IP_TUNNEL_SEQ_BIT, tunnel->parms.i_flags)) {
- if (!test_bit(IP_TUNNEL_SEQ_BIT, tpi->flags) ||
- (tunnel->i_seqno && (s32)(ntohl(tpi->seq) - tunnel->i_seqno) < 0)) {
+ if (!test_bit(IP_TUNNEL_SEQ_BIT, tpi->flags)) {
DEV_STATS_INC(tunnel->dev, rx_fifo_errors);
DEV_STATS_INC(tunnel->dev, rx_errors);
+ reason = SKB_DROP_REASON_TNL_OPT_MISMATCH;
+ goto drop;
+ }
+ if (tunnel->i_seqno &&
+ (s32)(ntohl(tpi->seq) - tunnel->i_seqno) < 0) {
+ DEV_STATS_INC(tunnel->dev, rx_fifo_errors);
+ DEV_STATS_INC(tunnel->dev, rx_errors);
+ reason = SKB_DROP_REASON_TNL_OLD_SEQ;
goto drop;
}
tunnel->i_seqno = ntohl(tpi->seq) + 1;
@@ -419,7 +428,8 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
skb_set_network_header(skb, (tunnel->dev->type == ARPHRD_ETHER) ? ETH_HLEN : 0);
- if (!pskb_inet_may_pull(skb)) {
+ reason = pskb_inet_may_pull_reason(skb);
+ if (reason) {
DEV_STATS_INC(tunnel->dev, rx_length_errors);
DEV_STATS_INC(tunnel->dev, rx_errors);
goto drop;
@@ -434,6 +444,7 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
if (err > 1) {
DEV_STATS_INC(tunnel->dev, rx_frame_errors);
DEV_STATS_INC(tunnel->dev, rx_errors);
+ reason = SKB_DROP_REASON_IP_TUNNEL_ECN;
goto drop;
}
}
@@ -457,7 +468,7 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
drop:
if (tun_dst)
dst_release((struct dst_entry *)tun_dst);
- kfree_skb(skb);
+ kfree_skb_reason(skb, reason);
return 0;
}
EXPORT_SYMBOL_GPL(ip_tunnel_rcv);
--
2.47.3
next prev parent reply other threads:[~2026-09-22 22:15 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-22 22:14 [PATCH net-next v4 00/10] tunnels: add core and gre drop reasons Anton Danilov
2026-09-22 22:14 ` Anton Danilov [this message]
2026-09-22 22:14 ` [PATCH net-next v4 02/10] ip6_tunnel: add drop reasons to the generic RX path Anton Danilov
2026-09-22 22:15 ` [PATCH net-next v4 03/10] gre: make gre_parse_header() report a drop reason Anton Danilov
2026-09-23 14:59 ` Ido Schimmel
2026-09-22 22:15 ` [PATCH net-next v4 04/10] ip_tunnel: add __iptunnel_pull_header_reason() Anton Danilov
2026-09-23 15:41 ` Ido Schimmel
2026-09-22 22:15 ` [PATCH net-next v4 05/10] ip_gre: add drop reasons to the RX path Anton Danilov
2026-09-22 22:15 ` [PATCH net-next v4 06/10] ip6_gre: " Anton Danilov
2026-09-22 22:15 ` [PATCH net-next v4 07/10] ip_tunnel: add drop reasons to the transmit path Anton Danilov
2026-09-23 15:53 ` Ido Schimmel
2026-09-22 22:15 ` [PATCH net-next v4 08/10] ip_gre: " Anton Danilov
2026-09-22 22:15 ` [PATCH net-next v4 09/10] ip6_gre: make prepare_ip6gre_xmit_other() void Anton Danilov
2026-09-22 22:15 ` [PATCH net-next v4 10/10] ip6_tunnel: add drop reasons to the transmit path Anton Danilov
2026-09-23 14:19 ` [PATCH net-next v4 00/10] tunnels: add core and gre drop reasons Ido Schimmel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260922221507.3268127-2-littlesmilingcloud@gmail.com \
--to=littlesmilingcloud@gmail.com \
--cc=davem@davemloft.net \
--cc=dsahern@kernel.org \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=idosch@nvidia.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®