From: Anton Danilov <littlesmilingcloud@gmail.com>
To: netdev@vger.kernel.org
Cc: "David S . Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@kernel.org>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Simon Horman <horms@kernel.org>, David Ahern <dsahern@kernel.org>,
Ido Schimmel <idosch@nvidia.com>,
linux-kernel@vger.kernel.org
Subject: [PATCH net-next v6 2/8] ip6_tunnel: add drop reasons to the receive path
Date: Tue, 10 Nov 2026 23:20:15 +0300 [thread overview]
Message-ID: <20261110202021.821224-3-littlesmilingcloud@gmail.com> (raw)
In-Reply-To: <20261110202021.821224-1-littlesmilingcloud@gmail.com>
__ip6_tnl_rcv() mirrors its IPv4 counterpart: all of its failures share
a single plain kfree_skb(). Reuse the drop reasons that ip_tunnel_rcv()
now reports and the ones the length helpers already return.
Note that skb_vlan_inet_prepare() returns an enum skb_drop_reason that
has so far been discarded, and that the ETH_HLEN check gets one by
calling pskb_may_pull_reason() instead of pskb_may_pull().
__ip6_tnl_rcv() is reached two ways: ip6_gre (ip6gre, ip6gretap,
ip6erspan) goes through the exported ip6_tnl_rcv(), while the
ip6_tunnel encapsulations (ip4ip6, ip6ip6, mplsip6) reach it from
ipxip6_rcv(). Only ip6_gre sets the checksum and sequence number bits:
tpi_v4, tpi_v6 and tpi_mpls carry nothing but .proto, and unlike ipip
and sit, ip6_tunnel stores IFLA_IPTUN_FLAGS in parms.flags, not in
parms.i_flags. So the option mismatch and the old sequence reasons are
reachable through ip6_gre alone.
ipxip6_rcv() drops the packets it does not hand to __ip6_tnl_rcv() with
a plain kfree_skb() as well. Give them a reason too:
SKB_DROP_REASON_UNHANDLED_PROTO when the payload is not the one the
tunnel mode carries, SKB_DROP_REASON_XFRM_POLICY when the xfrm policy
check fails, the reason iptunnel_pull_header() returns and
SKB_DROP_REASON_NOMEM when the metadata dst cannot be allocated.
A packet that ip6_tnl_rcv_ctl() refuses stays
SKB_DROP_REASON_NOT_SPECIFIED, now set explicitly. The helper refuses
when the outer destination is not a usable local address, such as a
tentative one, when the outer source belongs to this host, and when the
tunnel cannot receive with the addresses of the packet, and it returns
only 0 or 1. Telling these apart needs ip6_tnl_rcv_ctl() and its
transmit counterpart ip6_tnl_xmit_ctl() to return a reason, which is
left for a follow-up.
ipxip6_rcv() and __ip6_tnl_rcv() follow the rule of ip_tunnel_rcv() for
the reason: it is initialized to SKB_DROP_REASON_NOT_SPECIFIED, and
every jump to the drop label comes with a reason of its own.
Signed-off-by: Anton Danilov <littlesmilingcloud@gmail.com>
---
net/ipv6/ip6_tunnel.c | 45 +++++++++++++++++++++++++++++++------------
1 file changed, 33 insertions(+), 12 deletions(-)
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 64a184bca467..4912b08228a1 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -813,6 +813,7 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb,
struct sk_buff *skb),
bool log_ecn_err)
{
+ enum skb_drop_reason reason = SKB_DROP_REASON_NOT_SPECIFIED;
const struct ipv6hdr *ipv6h;
int nh, err;
@@ -820,15 +821,22 @@ static int __ip6_tnl_rcv(struct ip6_tnl *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_TUNNEL_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_TUNNEL_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_TUNNEL_OLD_SEQ;
goto drop;
}
tunnel->i_seqno = ntohl(tpi->seq) + 1;
@@ -838,7 +846,8 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb,
/* Warning: All skb pointers will be invalidated! */
if (tunnel->dev->type == ARPHRD_ETHER) {
- if (!pskb_may_pull(skb, ETH_HLEN)) {
+ reason = pskb_may_pull_reason(skb, ETH_HLEN);
+ if (reason) {
DEV_STATS_INC(tunnel->dev, rx_length_errors);
DEV_STATS_INC(tunnel->dev, rx_errors);
goto drop;
@@ -859,7 +868,8 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb,
skb_reset_network_header(skb);
- if (skb_vlan_inet_prepare(skb, true)) {
+ reason = skb_vlan_inet_prepare(skb, true);
+ if (reason) {
DEV_STATS_INC(tunnel->dev, rx_length_errors);
DEV_STATS_INC(tunnel->dev, rx_errors);
goto drop;
@@ -881,6 +891,7 @@ static int __ip6_tnl_rcv(struct ip6_tnl *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;
}
}
@@ -898,7 +909,7 @@ static int __ip6_tnl_rcv(struct ip6_tnl *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;
}
@@ -941,6 +952,7 @@ static int ipxip6_rcv(struct sk_buff *skb, u8 ipproto,
const struct ipv6hdr *ipv6h,
struct sk_buff *skb))
{
+ enum skb_drop_reason reason = SKB_DROP_REASON_NOT_SPECIFIED;
struct ip6_tnl *t;
const struct ipv6hdr *ipv6h = ipv6_hdr(skb);
struct metadata_dst *tun_dst = NULL;
@@ -952,21 +964,30 @@ static int ipxip6_rcv(struct sk_buff *skb, u8 ipproto,
if (t) {
u8 tproto = READ_ONCE(t->parms.proto);
- if (tproto != ipproto && tproto != 0)
+ if (tproto != ipproto && tproto != 0) {
+ reason = SKB_DROP_REASON_UNHANDLED_PROTO;
goto drop;
- if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
+ }
+ if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
+ reason = SKB_DROP_REASON_XFRM_POLICY;
goto drop;
+ }
ipv6h = ipv6_hdr(skb);
- if (!ip6_tnl_rcv_ctl(t, &ipv6h->daddr, &ipv6h->saddr))
+ if (!ip6_tnl_rcv_ctl(t, &ipv6h->daddr, &ipv6h->saddr)) {
+ reason = SKB_DROP_REASON_NOT_SPECIFIED;
goto drop;
- if (iptunnel_pull_header(skb, 0, tpi->proto, false))
+ }
+ reason = iptunnel_pull_header(skb, 0, tpi->proto, false);
+ if (reason)
goto drop;
if (t->parms.collect_md) {
IP_TUNNEL_DECLARE_FLAGS(flags) = { };
tun_dst = ipv6_tun_rx_dst(skb, flags, 0, 0);
- if (!tun_dst)
+ if (!tun_dst) {
+ reason = SKB_DROP_REASON_NOMEM;
goto drop;
+ }
}
ret = __ip6_tnl_rcv(t, skb, tpi, tun_dst, dscp_ecn_decapsulate,
log_ecn_error);
@@ -978,7 +999,7 @@ static int ipxip6_rcv(struct sk_buff *skb, u8 ipproto,
drop:
rcu_read_unlock();
- kfree_skb(skb);
+ kfree_skb_reason(skb, reason);
return 0;
}
--
2.47.3
next prev parent reply other threads:[~2026-11-10 20:20 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-10 20:20 [PATCH net-next v6 0/8] tunnels: add core and gre drop reasons Anton Danilov
2026-11-10 20:20 ` [PATCH net-next v6 1/8] ip_tunnel: add drop reasons to the generic RX path Anton Danilov
2026-11-10 20:20 ` Anton Danilov [this message]
2026-11-10 20:20 ` [PATCH net-next v6 3/8] gre: make gre_parse_header() report a drop reason Anton Danilov
2026-11-10 20:20 ` [PATCH net-next v6 4/8] ip_gre: add drop reasons to the RX path Anton Danilov
2026-11-10 20:20 ` [PATCH net-next v6 5/8] ip6_gre: " Anton Danilov
2026-11-10 20:20 ` [PATCH net-next v6 6/8] ip_tunnel: make ip_tunnel_encap() return a drop reason Anton Danilov
2026-11-10 20:20 ` [PATCH net-next v6 7/8] ip_tunnel: add drop reasons to the transmit path Anton Danilov
2026-11-10 20:20 ` [PATCH net-next v6 8/8] ip_gre: " Anton Danilov
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=20261110202021.821224-3-littlesmilingcloud@gmail.com \
--to=littlesmilingcloud@gmail.com \
--cc=davem@davemloft.net \
--cc=dsahern@kernel.org \
--cc=edumazet@kernel.org \
--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®