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>,
Simon Horman <horms@kernel.org>, David Ahern <dsahern@kernel.org>,
Ido Schimmel <idosch@nvidia.com>,
Andrew Lunn <andrew+netdev@lunn.ch>,
linux-kernel@vger.kernel.org
Subject: [PATCH net-next v5 13/14] ip6_gre: add drop reasons to the transmit path
Date: Wed, 30 Sep 2026 21:39:09 +0300 [thread overview]
Message-ID: <20260930183910.3151873-14-littlesmilingcloud@gmail.com> (raw)
In-Reply-To: <20260930183910.3151873-1-littlesmilingcloud@gmail.com>
The previous patch made the ip6_gre helpers return the drop reason of
ip6_tnl_xmit() and their own, but ip6gre_tunnel_xmit() and
ip6erspan_tunnel_xmit() still free the packet with a plain kfree_skb().
Free it with the reason instead, and give the drops of the handlers
themselves one, from the same set:
- the length reason from pskb_inet_may_pull_reason(), as in ip_gre,
- SKB_DROP_REASON_NO_TX_TARGET for a device without a remote address
that is not collect_md, every packet of which ip6_tnl_xmit_ctl()
refuses, as the handlers pass it the addresses of the device;
ip6_tnl_xmit() reports an NBMA tunnel that found no endpoint the
same way,
- SKB_DROP_REASON_DEV_READY for the other refusals of
ip6_tnl_xmit_ctl(), which, as the previous patch explains, include a
routing loop,
- SKB_DROP_REASON_NOMEM for the offload setup, the trim of a packet
longer than the MTU and the headroom,
- SKB_DROP_REASON_TUNNEL_TXINFO for the collect_md metadata checks of
ip6erspan, and for a packet without IPv6 metadata in ip6gre (see
below),
- SKB_DROP_REASON_UNHANDLED_PROTO for an ERSPAN version that is not
implemented,
- SKB_DROP_REASON_RECURSION_LIMIT and SKB_DROP_REASON_IPV6_BAD_EXTHDR
for the checks that ip6erspan_tunnel_xmit() does itself, the same as
in ip6gre_xmit_ipv6().
ip6gre_tunnel_xmit() looks up the metadata of a collect_md device before
it passes the packet to a helper, but leaves the drop of a packet
without usable metadata, missing or not of the IPv6 family, to the
helpers, and ip6gre_xmit_ipv6() checks the source address first. The
raddr of such a device is ::, so such a packet sent from ::, like the
device's own DAD probe, would be reported as
SKB_DROP_REASON_RECURSION_LIMIT, and other such packets as
SKB_DROP_REASON_TUNNEL_TXINFO. Drop it right after the lookup instead,
as SKB_DROP_REASON_TUNNEL_TXINFO, with the test ip6erspan_tunnel_xmit()
uses; the IPv4 handlers also test presence and family together. The
helpers dropped such a packet before ip6_tnl_xmit() in any case, and
tx_err counts it by the result of the lookup, so only the reason
changes; the test in __gre6_xmit() stays as a safeguard. A packet from
:: that carries IPv6 metadata still meets the check in
ip6gre_xmit_ipv6().
Such an ip6gre device is an NBMA tunnel: ip6gre_header() puts the
endpoint of the packet in its outer header, and __gre6_xmit() would
take it from there, but ip6gre_tunnel_xmit() refuses the packet before
that, so the device sends nothing. This patch does not change that; it
reports these drops like those of an ip6gretap or ip6erspan device
without a remote address, which has no endpoint at all.
Assisted-by: LLM
Signed-off-by: Anton Danilov <littlesmilingcloud@gmail.com>
---
net/ipv6/ip6_gre.c | 73 ++++++++++++++++++++++++++++++++++++----------
1 file changed, 58 insertions(+), 15 deletions(-)
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 9e94ea6b6c20..dbca78230815 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -889,14 +889,28 @@ static netdev_tx_t ip6gre_tunnel_xmit(struct sk_buff *skb,
enum skb_drop_reason reason;
__be16 payload_protocol;
- if (!pskb_inet_may_pull(skb))
+ reason = pskb_inet_may_pull_reason(skb);
+ if (reason)
goto tx_err;
- if (!ip6_tnl_xmit_ctl(t, &t->parms.laddr, &t->parms.raddr))
+ if (!t->parms.collect_md && ipv6_addr_any(&t->parms.raddr)) {
+ reason = SKB_DROP_REASON_NO_TX_TARGET;
goto tx_err;
+ }
- if (t->parms.collect_md)
+ if (!ip6_tnl_xmit_ctl(t, &t->parms.laddr, &t->parms.raddr)) {
+ reason = SKB_DROP_REASON_DEV_READY;
+ goto tx_err;
+ }
+
+ if (t->parms.collect_md) {
tun_info = skb_tunnel_info_txcheck(skb);
+ if (IS_ERR(tun_info) ||
+ unlikely(ip_tunnel_info_af(tun_info) != AF_INET6)) {
+ reason = SKB_DROP_REASON_TUNNEL_TXINFO;
+ goto tx_err;
+ }
+ }
payload_protocol = skb_protocol(skb, true);
switch (payload_protocol) {
@@ -917,10 +931,11 @@ static netdev_tx_t ip6gre_tunnel_xmit(struct sk_buff *skb,
return NETDEV_TX_OK;
tx_err:
+ reason = reason ?: SKB_DROP_REASON_NOT_SPECIFIED;
if (!IS_ERR(tun_info))
DEV_STATS_INC(dev, tx_errors);
DEV_STATS_INC(dev, tx_dropped);
- kfree_skb(skb);
+ kfree_skb_reason(skb, reason);
return NETDEV_TX_OK;
}
@@ -940,18 +955,30 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
__u32 mtu;
int nhoff;
- if (!pskb_inet_may_pull(skb))
+ reason = pskb_inet_may_pull_reason(skb);
+ if (reason)
goto tx_err;
- if (!ip6_tnl_xmit_ctl(t, &t->parms.laddr, &t->parms.raddr))
+ if (!t->parms.collect_md && ipv6_addr_any(&t->parms.raddr)) {
+ reason = SKB_DROP_REASON_NO_TX_TARGET;
goto tx_err;
+ }
- if (gre_handle_offloads(skb, false))
+ if (!ip6_tnl_xmit_ctl(t, &t->parms.laddr, &t->parms.raddr)) {
+ reason = SKB_DROP_REASON_DEV_READY;
goto tx_err;
+ }
+
+ if (gre_handle_offloads(skb, false)) {
+ reason = SKB_DROP_REASON_NOMEM;
+ goto tx_err;
+ }
if (skb->len > dev->mtu + dev->hard_header_len) {
- if (pskb_trim(skb, dev->mtu + dev->hard_header_len))
+ if (pskb_trim(skb, dev->mtu + dev->hard_header_len)) {
+ reason = SKB_DROP_REASON_NOMEM;
goto tx_err;
+ }
truncate = true;
}
@@ -971,8 +998,10 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
truncate = true;
}
- if (skb_cow_head(skb, dev->needed_headroom ?: t->hlen))
+ if (skb_cow_head(skb, dev->needed_headroom ?: t->hlen)) {
+ reason = SKB_DROP_REASON_NOMEM;
goto tx_err;
+ }
IPCB(skb)->flags = 0;
@@ -986,8 +1015,10 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
tun_info = skb_tunnel_info_txcheck(skb);
if (IS_ERR(tun_info) ||
- unlikely(ip_tunnel_info_af(tun_info) != AF_INET6))
+ unlikely(ip_tunnel_info_af(tun_info) != AF_INET6)) {
+ reason = SKB_DROP_REASON_TUNNEL_TXINFO;
goto tx_err;
+ }
key = &tun_info->key;
memset(&fl6, 0, sizeof(fl6));
@@ -999,10 +1030,14 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
dsfield = key->tos;
if (!test_bit(IP_TUNNEL_ERSPAN_OPT_BIT,
- tun_info->key.tun_flags))
+ tun_info->key.tun_flags)) {
+ reason = SKB_DROP_REASON_TUNNEL_TXINFO;
goto tx_err;
- if (tun_info->options_len < sizeof(*md))
+ }
+ if (tun_info->options_len < sizeof(*md)) {
+ reason = SKB_DROP_REASON_TUNNEL_TXINFO;
goto tx_err;
+ }
md = ip_tunnel_info_opts(tun_info);
tun_id = tunnel_id_to_key32(key->tun_id);
@@ -1020,6 +1055,7 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
truncate, false);
proto = htons(ETH_P_ERSPAN2);
} else {
+ reason = SKB_DROP_REASON_UNHANDLED_PROTO;
goto tx_err;
}
} else {
@@ -1030,11 +1066,16 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
&dsfield, &encap_limit);
break;
case htons(ETH_P_IPV6):
- if (ipv6_addr_equal(&t->parms.raddr, &ipv6_hdr(skb)->saddr))
+ if (ipv6_addr_equal(&t->parms.raddr,
+ &ipv6_hdr(skb)->saddr)) {
+ reason = SKB_DROP_REASON_RECURSION_LIMIT;
goto tx_err;
+ }
if (prepare_ip6gre_xmit_ipv6(skb, dev, &fl6,
- &dsfield, &encap_limit))
+ &dsfield, &encap_limit)) {
+ reason = SKB_DROP_REASON_IPV6_BAD_EXTHDR;
goto tx_err;
+ }
break;
default:
memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6));
@@ -1053,6 +1094,7 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
truncate, false);
proto = htons(ETH_P_ERSPAN2);
} else {
+ reason = SKB_DROP_REASON_UNHANDLED_PROTO;
goto tx_err;
}
@@ -1087,10 +1129,11 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
return NETDEV_TX_OK;
tx_err:
+ reason = reason ?: SKB_DROP_REASON_NOT_SPECIFIED;
if (!IS_ERR(tun_info))
DEV_STATS_INC(dev, tx_errors);
DEV_STATS_INC(dev, tx_dropped);
- kfree_skb(skb);
+ kfree_skb_reason(skb, reason);
return NETDEV_TX_OK;
}
--
2.47.3
next prev parent reply other threads:[~2026-09-30 18:39 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-30 18:38 [PATCH net-next v5 00/14] tunnels: add core and gre drop reasons Anton Danilov
2026-09-30 18:38 ` [PATCH net-next v5 01/14] vxlan: rename the drop reasons for use by other tunnels Anton Danilov
2026-09-30 18:38 ` [PATCH net-next v5 02/14] ip_tunnel: make __iptunnel_pull_header() return a drop reason Anton Danilov
2026-09-30 18:38 ` [PATCH net-next v5 03/14] vxlan: report the drop reason of __iptunnel_pull_header() Anton Danilov
2026-09-30 18:39 ` [PATCH net-next v5 04/14] ip_tunnel: add drop reasons to the generic RX path Anton Danilov
2026-09-30 18:39 ` [PATCH net-next v5 05/14] ip6_tunnel: add drop reasons to the receive path Anton Danilov
2026-09-30 18:39 ` [PATCH net-next v5 06/14] gre: make gre_parse_header() report a drop reason Anton Danilov
2026-09-30 18:39 ` [PATCH net-next v5 07/14] ip_gre: add drop reasons to the RX path Anton Danilov
2026-09-30 18:39 ` [PATCH net-next v5 08/14] ip6_gre: " Anton Danilov
2026-09-30 18:39 ` [PATCH net-next v5 09/14] ip_tunnel: add drop reasons to the transmit path Anton Danilov
2026-09-30 18:39 ` [PATCH net-next v5 10/14] ip_gre: " Anton Danilov
2026-09-30 18:39 ` [PATCH net-next v5 11/14] ip6_gre: make prepare_ip6gre_xmit_other() void Anton Danilov
2026-09-30 18:39 ` [PATCH net-next v5 12/14] ip6_tunnel: make ip6_tnl_xmit() return a drop reason Anton Danilov
2026-09-30 18:39 ` Anton Danilov [this message]
2026-09-30 18:39 ` [PATCH net-next v5 14/14] vxlan: report a circular route as SKB_DROP_REASON_RECURSION_LIMIT 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=20260930183910.3151873-14-littlesmilingcloud@gmail.com \
--to=littlesmilingcloud@gmail.com \
--cc=andrew+netdev@lunn.ch \
--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®