From nobody Sat Sep 26 13:46:47 2026 Received: from mail-lf1-f47.google.com (mail-lf1-f47.google.com [209.85.167.47]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8EC233AC0FC for ; Mon, 31 Aug 2026 21:51:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788213119; cv=none; b=d2R30DWDA3CJg+YRv14+6xganLGVX7LfRH381+5cmkv4Kv19A63vQ3P2wyAYP0RDltQ0stigMg26TbdGa4cW6FSpKWCm3UiOOODpSSLEJsiXtx+pnrSNrTKSk0H7CMa1eCT97Y01RIXf68td3I1U+bnrNCgo6Wb9yKBfaB6R9ls= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788213119; c=relaxed/simple; bh=0Vj8tzfWFlfJ24u2ZpDpxJ2AGt2qvJdpJaNpRHArSAM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=AuR0bgsjMYLApCQHpTV9P93qwk0qwfCv+xQufsR4HuXpxje3XbePgr4OgdSu9nes2hrpOS1Im9ILaEsKpc/W68Wb2U081G/Uq3pS3YtAF6XK1Xsapb/rLJaIrTwzZUo4EsVGU8E0Sh42h6Nt0iLPp09doOgoWVIZuq4orhBzfO8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=nnMjiiU+; arc=none smtp.client-ip=209.85.167.47 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="nnMjiiU+" Received: by mail-lf1-f47.google.com with SMTP id 2adb3069b0e04-5b5edf31ef4so2975034e87.1 for ; Mon, 31 Aug 2026 14:51:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788213114; x=1788817914; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=vmQ7GvgiZY3wByqIWh2v7F1IlCfje0depDGRFqZIt00=; b=nnMjiiU+32bf8E4kOxCXlBGfWNb8fySnaWckNwGAyc8lEo/SccYAa/5P3hoor+drub ABvZp/sVcIcXzMYCdFYvDxuAbJ05HtOGDd4NEV4Pu5A7hY6ZIabcskRjno0ykJwhDBPA nsquqfIQHFrzg/w/5tjNDHbCJp1RKUUmdg50vTJFCy4mTODgBWQpbvhX9JCz8DvxCZYZ Lz2uVjUBn1VM9fGHcn5Rf8lVyz3izJ7rwijI9cGYnVUD4Wgn1skyUC7IerPIhApiupJ9 eb519JTtuI60Qsu99GvbcnbeX0X8ylQsy4/TF0OgmabFYcplquy3/GirPalYXRbZLGJX PkaA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788213114; x=1788817914; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=vmQ7GvgiZY3wByqIWh2v7F1IlCfje0depDGRFqZIt00=; b=oEIBEMkWd7j2tBDKbmThMXNqzYdWcgfyGAmIgkh7GrQRpXzNlGezdnQVJj7VBWThB7 SCnqLvcQnDpn/rq3H9WIKUPz1uxxQ/NThcZ4VF+HLXG3NeRB9gEXF2Eq8oLSFXYiITOM k1OEfHcAmL61pGf1wDzIIVQE6w4YtPSpPG3OEU0etQZG+AqidztkjSOa0sAdAPbnmugI rF4yuT7DSYXigQa9tqjzCQ8xS/IRW0Epb5d+RFid4m/gHBCP/4uScNL6FHNb/XfoFAaR g3qVO77jaNU2VN+ZS24nP5/gVEC0F3CwmHFyTO5LpPi9FUXJdXuzOjcDB9GX4/hA1DhP k1HQ== X-Forwarded-Encrypted: i=1; AKwUvBz/JipwE4Tj1szRXes1w38+Us5+DZITFxRZkVu++/4kMuhIak5D36u1gPOKZrbcJrNAS0Nt7NLuEwNet4w=@vger.kernel.org X-Gm-Message-State: AFuF++nOEt9q7thbl0Tk39JYPilRKj6BiM6/ZWhjQQN/ZZNfAwpqM6Mn 2Y7c7p+VhAfDDTffI331zqfRQigz0kswIFexL0FjhyZSji/AWUoUL8fs X-Gm-Gg: AYBFou0iFuk0SI3tiZIh9aCCijlApH196fwhSCD16k+gx+r4M1NR7Xmyk826Waz5iwP ZLfl1QqAqWwNZzT+yKunwqe+TXFmBQR1d6FMDKDRsd4Mw2DicJCcmQ59ZB3LWIryG41oJmGF63q IJJU2H29rJiPskFhGmUDicNiPy8qvF0aDl2OytE4UriVYDCbydX6OEhhPmJRDcCMfqcPRuHioWq 3x5jovQqstOun4FyerePXPXMk4hd8fa92lw9ajneSeBDTR2h8q9Um/YM5oVgO9eWcYPkuOXEwqq V1+YgdWpqywtWKUXbqNjp0L9cb8DTyueDnNdB8kk7Fl3/+Twe6px88ap/vZiYIZbyRRqBZqW6/0 8MYeCezJpIRsXh7bD45F/kFBMGbPuzBnbAUcdZlU4cbxxUT0rt4LzmJEbOilvJc1EWUlr8IfuMT bdwEKxhQWXUPHpIxzfo1xg1r3DBFYlCugUp+MJB3xy/GMLjfJMmWoc+OHTpk5n7mVnKw5/HZLxn mRhZl4E2ElDg67EENTNXGfdGecCDL6oZg== X-Received: by 2002:a05:6512:3e0f:b0:5b0:eda:de1f with SMTP id 2adb3069b0e04-5b5e68ba39amr7362736e87.6.1788213113392; Mon, 31 Aug 2026 14:51:53 -0700 (PDT) Received: from dau-home-pc.. ([212.35.184.237]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b5e8a06a77sm2388782e87.48.2026.08.31.14.51.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Aug 2026 14:51:52 -0700 (PDT) From: Anton Danilov To: netdev@vger.kernel.org Cc: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , David Ahern , Simon Horman , Shuah Khan , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH net-next 01/11] ip_tunnel: add drop reasons to the generic RX path Date: Tue, 1 Sep 2026 00:51:27 +0300 Message-ID: <20260831215137.549324-2-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260831215137.549324-1-littlesmilingcloud@gmail.com> References: <20260831215137.549324-1-littlesmilingcloud@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" ip_tunnel_rcv() collapses four distinct failures into a single plain kfree_skb(), so a packet dropped there simply vanishes: - 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). 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 reported to drop_monitor or to the skb:kfree_skb tracepoint. Add two drop reasons for the tunnel specific cases and reuse the existing ones for the rest: - SKB_DROP_REASON_IP_TUNNEL_CFG_OPTS_MISMATCH is used when the packet does not carry the checksum or the sequence number option the tunnel is configured for. 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_IP_TUNNEL_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 i_seqno catches up. - pskb_inet_may_pull_reason() already computes a drop reason, SKB_DROP_REASON_PKT_TOO_SMALL or SKB_DROP_REASON_NOMEM, which was discarded so far. - 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 test 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 checksum and the sequence number options only exist for GRE, so the two new reasons are reachable through ip_gre alone, while the length and the ECN ones apply to all three. Assisted-by: Claude-Code:claude-opus-5 Signed-off-by: Anton Danilov --- include/net/dropreason-core.h | 16 ++++++++++++++++ net/ipv4/ip_tunnel.c | 19 +++++++++++++++---- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/include/net/dropreason-core.h b/include/net/dropreason-core.h index 2f312d1f67d6..40f94ecb912a 100644 --- a/include/net/dropreason-core.h +++ b/include/net/dropreason-core.h @@ -128,6 +128,8 @@ FN(PSP_INPUT) \ FN(PSP_OUTPUT) \ FN(RECURSION_LIMIT) \ + FN(IP_TUNNEL_CFG_OPTS_MISMATCH) \ + FN(IP_TUNNEL_OLD_SEQ) \ FNe(MAX) =20 /** @@ -606,6 +608,20 @@ 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_IP_TUNNEL_CFG_OPTS_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. + */ + SKB_DROP_REASON_IP_TUNNEL_CFG_OPTS_MISMATCH, + /** + * @SKB_DROP_REASON_IP_TUNNEL_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_IP_TUNNEL_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 e6bcf01411d0..ab8bae8ba781 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -379,6 +379,7 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_b= uff *skb, bool log_ecn_error) { const struct iphdr *iph =3D ip_hdr(skb); + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; int nh, err; =20 #ifdef CONFIG_NET_IPGRE_BROADCAST @@ -392,14 +393,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 =3D SKB_DROP_REASON_IP_TUNNEL_CFG_OPTS_MISMATCH; goto drop; } =20 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 =3D SKB_DROP_REASON_IP_TUNNEL_CFG_OPTS_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 =3D SKB_DROP_REASON_IP_TUNNEL_OLD_SEQ; goto drop; } tunnel->i_seqno =3D ntohl(tpi->seq) + 1; @@ -413,7 +422,8 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_b= uff *skb, =20 skb_set_network_header(skb, (tunnel->dev->type =3D=3D ARPHRD_ETHER) ? ETH= _HLEN : 0); =20 - if (!pskb_inet_may_pull(skb)) { + reason =3D 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; @@ -428,6 +438,7 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_b= uff *skb, if (err > 1) { DEV_STATS_INC(tunnel->dev, rx_frame_errors); DEV_STATS_INC(tunnel->dev, rx_errors); + reason =3D SKB_DROP_REASON_IP_TUNNEL_ECN; goto drop; } } @@ -451,7 +462,7 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_b= uff *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); --=20 2.47.3 From nobody Sat Sep 26 13:46:47 2026 Received: from mail-lf1-f41.google.com (mail-lf1-f41.google.com [209.85.167.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C53B83B14D0 for ; Mon, 31 Aug 2026 21:51:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788213124; cv=none; b=KECJhYpjDGO4jKnXnKVwgyJgO5GiDj7/UoifNV68AljncEcs0SVZFGO4zFUMKOsuHUk2w09U5jV1HVxAl/1J2MLsa2mGuSDMssB4SC8gaQ6zSqRFIrnbr/+4ZHpYZxpe30y9qMFn3GWKz73NKqUjlAU240nIcxuuVKYg0+OveZU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788213124; c=relaxed/simple; bh=3qvZ3aiO+s+CVAa4MERALYDlYKjhPNcy4xFtFfaY6/M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Jf5+pSwwH/y3hoaXyDNwvX2AR+3cvmpse4SaGUqxKUI/U5gG0vdi4ipMEV2WltwQw8TxvhkOKsoDjZ3CZ4s4FYJJ275BAX2iWQYR7he+3TJMUV5zvJlNVQ2vsqL9dpDgO6xVRjhnbI3ysQgQkkB/HfZXIdR2V3tRqoaibtjOfQo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=N16BYGlx; arc=none smtp.client-ip=209.85.167.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="N16BYGlx" Received: by mail-lf1-f41.google.com with SMTP id 2adb3069b0e04-5b15dcaca31so3284029e87.0 for ; Mon, 31 Aug 2026 14:51:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788213115; x=1788817915; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=2NyiM+FHtIF3Ks/VyMyFTJauOhca6iS4MuHeOc8+lYc=; b=N16BYGlxO4G1pur2uOucSPNCBDx88uG9h0z67tYE1BE4K4IzYXu6iflRAaY4t3bNzU Pn6DYwzbnJmsPUdJk3mT6jv9uRCw1/tv117jQhLp2YxYpH2e8ArRn7ydV5cG87HjDDmC lkqh8o8aaI3Bays1lRE1hnYREwFyontGH3O/RBGR64cyVnCsyVVkFB5E3SNKsA8CuU/B M894k/KQ8fbiL7q5v7iEfmR3a7zpl2I5aUVRycMMrn0SI6gTLoN/WgyZ11vUBazEfxV4 HddbPvZOsbyPC7NJKvocTHCUpOQHogd7CjnllnpZ7d3fnNKr/PAylsb4I/UFvDIYUXIE ln3w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788213115; x=1788817915; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=2NyiM+FHtIF3Ks/VyMyFTJauOhca6iS4MuHeOc8+lYc=; b=tPobucqpQg2Ct+CPx0WFMHChnrfXv9TtYBJyHDCcsih6BCBzueTfqSdDqdGRKcH2UL sTicozHOau5YkINLGyAs0BQQK6cxT1CNI/+JTMcLgtqhbZ1pVbOpBou6F+DqX2tUGP8w COgebsz2fPskci70hV7Qfrnq8ONCeNQZAs8c1+4qVwgdoWad7ErJRnuVEdVGtKgrfPZQ 6XHN7VoqoYn420vft/UiZ6lZMjcu2iSUhTK42zqs6RcaL5uVFJrBBgY38CNlROerSbsn aiGsfKkG5nw1gjLL772+Ywik6+Dhmy5PpHhfhHWDcZnTMMoHFgN4OAOUEnN4Y4s60eXR +LxQ== X-Forwarded-Encrypted: i=1; AKwUvBw0bKs6DJwQv5qUSx6i7bj/HgeK2oQG062tRxGY6Mo2qvtAtgewEneIalNKMER5EN5Zum2qVdhmpqzs5Sg=@vger.kernel.org X-Gm-Message-State: AFuF++kwhhhMqPAt7j24mC98m3nUHYM8j9E4kHPk6GWGI0U/jAp6c1YH VbECElQl0N+2EnvW2HCaGgS22pEu5E81IVqZQ5l2QY0VQ8gpFPqrbPIT X-Gm-Gg: AYBFou2vwDEfjN47LeMcKBXVRChmeDVsMullcPxTNHE82H5WCP4P0t3f5NsjDLMPpyC TwfgTV6+9Xo7Dw9689tbPG6gpjDmJKsqDPtk/RA8sNj1gyglpe2ZI+GKAXVpisN0Pqi3GP70hcG BnOO9QXBWPtbrPPRO9C0UsASKt7Xf3lXatJZ3p6oHyvAZjGTj2MtdbFdspbKm2AjuHPS+kM1bxB 6Twyyh2Nqn/lfHk39cx1j+5AWVdLwsRSo78opXSVxF7/LSVI/7bybX+SRC/m+s9YHxu7O7gNCiz yOoEVj/GpaCQkInW3ySAqPd8rq7NCimFvcDhgLl2hatOYEa5YFLDCvu4Iy4B78NPQUW9F7l5ym6 6esFC7nfKffPmuwUO369UhyJN7uPe5R4zVJHoWJe6Rtbr93yzDMM1GfKNJM/XK3h4on2L3kyBho O150ALEQIlcAF/94RAfLeu6/J1VTgINzb2kWBaSqoCn68CLMyM50cuuud96jiiQ6R5Mx/sVR5A/ KbTgwQCLEUJBRjkJkFrqzBXwovp4rRa3w== X-Received: by 2002:a05:6512:3053:b0:5ae:b7ce:9ca5 with SMTP id 2adb3069b0e04-5b5fe0902a3mr1665824e87.18.1788213114642; Mon, 31 Aug 2026 14:51:54 -0700 (PDT) Received: from dau-home-pc.. ([212.35.184.237]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b5e8a06a77sm2388782e87.48.2026.08.31.14.51.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Aug 2026 14:51:54 -0700 (PDT) From: Anton Danilov To: netdev@vger.kernel.org Cc: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , David Ahern , Simon Horman , Shuah Khan , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH net-next 02/11] ip6_tunnel: add drop reasons to the generic RX path Date: Tue, 1 Sep 2026 00:51:28 +0300 Message-ID: <20260831215137.549324-3-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260831215137.549324-1-littlesmilingcloud@gmail.com> References: <20260831215137.549324-1-littlesmilingcloud@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" __ip6_tnl_rcv() mirrors its IPv4 counterpart: five distinct failures share a single plain kfree_skb(). Reuse the drop reasons introduced for ip_tunnel_rcv() and the ones the length helpers already return. Note that skb_vlan_inet_prepare() returns an enum skb_drop_reason that was simply discarded, and that pskb_may_pull_reason() has been available all along. __ip6_tnl_rcv() is reached through ip6_tnl_rcv() from both ip6_tunnel (ip4ip6, ip6ip6) and ip6_gre (ip6gre, ip6gretap, erspan). As on the IPv4 side, only ip6_gre sets the checksum and sequence number bits, so the option mismatch and the old sequence reasons are reachable through it alone. Assisted-by: Claude-Code:claude-opus-5 Signed-off-by: Anton Danilov --- net/ipv6/ip6_tunnel.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index d5ff50a2ac01..85578fa125bc 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -814,21 +814,29 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, stru= ct sk_buff *skb, bool log_ecn_err) { const struct ipv6hdr *ipv6h; + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; int nh, err; =20 if (test_bit(IP_TUNNEL_CSUM_BIT, tunnel->parms.i_flags) !=3D test_bit(IP_TUNNEL_CSUM_BIT, tpi->flags)) { DEV_STATS_INC(tunnel->dev, rx_crc_errors); DEV_STATS_INC(tunnel->dev, rx_errors); + reason =3D SKB_DROP_REASON_IP_TUNNEL_CFG_OPTS_MISMATCH; goto drop; } =20 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 =3D SKB_DROP_REASON_IP_TUNNEL_CFG_OPTS_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 =3D SKB_DROP_REASON_IP_TUNNEL_OLD_SEQ; goto drop; } tunnel->i_seqno =3D ntohl(tpi->seq) + 1; @@ -838,7 +846,8 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct= sk_buff *skb, =20 /* Warning: All skb pointers will be invalidated! */ if (tunnel->dev->type =3D=3D ARPHRD_ETHER) { - if (!pskb_may_pull(skb, ETH_HLEN)) { + reason =3D 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, =20 skb_reset_network_header(skb); =20 - if (skb_vlan_inet_prepare(skb, true)) { + reason =3D 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 =3D 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; } =20 --=20 2.47.3 From nobody Sat Sep 26 13:46:47 2026 Received: from mail-lf1-f41.google.com (mail-lf1-f41.google.com [209.85.167.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 21BFB3A7193 for ; Mon, 31 Aug 2026 21:51:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788213123; cv=none; b=OVgb29xiRlLpUvjMkTTJL/r3zHS+JjyssUrpYy6XjG51EKwcJEr9dNH4FwOFpjXhocqWEZCRbgrxJ3Fa7J3ymT1sdemUX3gAMX+Jpe5w4Kdir+KsiMOFIBLLsu7N2F0QrU2bGB99/9gMzc6eEeuJOiWJjtAIeJPBxWlcsTE1d0M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788213123; c=relaxed/simple; bh=SxxpWGf9pRNuCBPbGr/fyUHi9zr4zYOgFQXFR7nQNrQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tZow4lOwV0rsjADHPvBu+xWEzuVFSCN55rC0D2diQz9/PmhKRx95JvJhXaoQ/JLs2TmwxzeIK01EFSX4zkueivGhBhCasqJdX5OVB1n0YbCHNC01FY2s4J+z7agNKwb2U5jtrSLxwc7mk3hQSqGKyNZSDiiMKleQw6WgEP45hiQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=IZW45Oax; arc=none smtp.client-ip=209.85.167.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="IZW45Oax" Received: by mail-lf1-f41.google.com with SMTP id 2adb3069b0e04-5b4ac3ba821so3331602e87.0 for ; Mon, 31 Aug 2026 14:51:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788213116; x=1788817916; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=bbE76zffGm5eOpH0C3tIgIhboyJHtbbJ0ikPzbJ0EIk=; b=IZW45OaxEUxvHoKjcnsr9wChlNf8GXlnum6sxfkVRdDf8pmah2CponSQ60gNfVpXs3 TOK6YmeHpH/wuBE8xiMEzt3bzKdojm57xsv3MRGN85/099fEitxaVTS/rqMTKlxmA0iE AG/ZWI68c0ubbuAS3HAKqXDMnascOhlV3BNCqvdH5WIUrlVHcYmyl7ktQWEjfRglTFmk yt1D1VGou6FqiyonG7kBtqS+lsk6yGC0Hjk0V2f+pFn1sTpUbWF3ub1r8mJK/83KyXZH WhLNMXoZcnZK9AyoH0LUTrlYzOxqc1AICrw+3wd0OQ7BBWr43KEC/WqNqRJv65fvzl7P qdMQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788213116; x=1788817916; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=bbE76zffGm5eOpH0C3tIgIhboyJHtbbJ0ikPzbJ0EIk=; b=oeMrpVIA4Hr5G1YJVWRBrF9RaropYTdVgjUj5vYtz6vROd3mosAT7zXkh+4i76p707 FlLxymSUYvznLN4W3QS4GQcL81Q1ouNsqErBWHiW3wouDCNaIjtLhZ6NKscjwt/6KBK5 J8GiAEazFR9Kjx5DK+Z3ynFlF/hiYgBFnKMHPluRhnF0NI30IvHhSToylSEwBiZiR2L8 8C5bel7AaX9baFb+rOIIN3+3W+AqKpRZQAGgr/+2fh0HQhjwxnu1QE0ro9XbY2cFfE/0 A6Hpa8enuRONg/e6oN+x/zSg7hyLIaVsueONXRY4xTurdgqpwpGbX85aoRNujN95j4Cn Zxdg== X-Forwarded-Encrypted: i=1; AKwUvBwqC022crrWu1miR7p0KSnD4qWvXJV3Uz5HRkZsnv2oetqr34KpM5WXt1ADEG7HW/i3+xJ9eUcR+/sENCE=@vger.kernel.org X-Gm-Message-State: AFuF++nRXrkGElinnqsjxkMDAqs3kkAvxafvhrWSeutNufDoWdVgR0N6 Qq5wL7GQFSQAqSvb0T1+aC3x90iJHHzECwSwNmaXSquA2wFsHgDU50Nl X-Gm-Gg: AYBFou2A5rLltiG8fxNW1shyeZiVeaq506Xr+xfRzk/7wIIYcCnwqTwAk375K2kU1fV VF91o/e89CISsVLluDd9KM9FCeWx6dqARbc51hUHmpr4G6B3Q5jmgUB0xDaBhPJx3b2jJAyOurX rMA85UQbetEU0ccAsDxiiZFQtGQZ4SQKftVjn261x2TAkurIOKzlE/te3EkLdkJCDSNVnlho3RF A06LSAEKN5tmmGjfv2WVugbfRotLMBMmiISP2DUSr21bxpU1k5v67BC5RLt1XriA1M1NXJqRkst LPIRya/kYq9p4CZUOsRKFGQKaRyTfwhvLtbTE5z0yDoLCGvRmOvL+sjaNNm2fh32ZV7S+hwb70m aNle+vd3cQGdUQTB1O+1Y9VH4v7ba07c1SXY0dCXRcZDItIjYQ7ksE7aJcQ3MxXsHnkY/bJcWre kfuwRWEDnmCx25zMOV1YmiF9GnRrJ6HEq+G1fr77o0axzSoSMiza4++B9fSG8IkgYKXt1Xz3hqi tuw8rF1H2IRRNRRg6qE6M1eGsfTdHgnkw== X-Received: by 2002:a05:6512:224c:b0:5b1:4c6f:92f9 with SMTP id 2adb3069b0e04-5b5fe0ea9f5mr1112459e87.20.1788213115911; Mon, 31 Aug 2026 14:51:55 -0700 (PDT) Received: from dau-home-pc.. ([212.35.184.237]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b5e8a06a77sm2388782e87.48.2026.08.31.14.51.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Aug 2026 14:51:55 -0700 (PDT) From: Anton Danilov To: netdev@vger.kernel.org Cc: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , David Ahern , Simon Horman , Shuah Khan , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH net-next 03/11] selftests: net: add a test for the tunnel RX drop reasons Date: Tue, 1 Sep 2026 00:51:29 +0300 Message-ID: <20260831215137.549324-4-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260831215137.549324-1-littlesmilingcloud@gmail.com> References: <20260831215137.549324-1-littlesmilingcloud@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Exercise the two drop reasons added to ip_tunnel_rcv() and __ip6_tnl_rcv() for the cases they were introduced for, on both GRE and ip6gre: - a receiver configured with 'iseq' or 'icsum' facing a sender that emits neither reports IP_TUNNEL_CFG_OPTS_MISMATCH, - recreating the tunnel device on the sender resets its outgoing sequence number the way a peer reboot would, and the receiver then reports IP_TUNNEL_OLD_SEQ. A control case, where both endpoints agree on the options, makes sure that no tunnel drop reason is reported when the packets are accepted. The reasons are read from the skb:kfree_skb tracepoint through a dedicated trace instance, so that the test neither disturbs nor depends on anything else using the tracing facility. The test is skipped when that instance cannot be set up. Assisted-by: Claude-Code:claude-opus-5 Signed-off-by: Anton Danilov --- tools/testing/selftests/net/Makefile | 1 + tools/testing/selftests/net/config | 1 + .../selftests/net/tunnel_drop_reasons.sh | 228 ++++++++++++++++++ 3 files changed, 230 insertions(+) create mode 100755 tools/testing/selftests/net/tunnel_drop_reasons.sh diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests= /net/Makefile index 0f5c178bc224..9acf364e8919 100644 --- a/tools/testing/selftests/net/Makefile +++ b/tools/testing/selftests/net/Makefile @@ -117,6 +117,7 @@ TEST_PROGS :=3D \ test_vxlan_vnifiltering.sh \ tfo_passive.sh \ traceroute.sh \ + tunnel_drop_reasons.sh \ txtimestamp.sh \ udpgro.sh \ udpgro_bench.sh \ diff --git a/tools/testing/selftests/net/config b/tools/testing/selftests/n= et/config index 30d5fcb09a83..281633ff3aa9 100644 --- a/tools/testing/selftests/net/config +++ b/tools/testing/selftests/net/config @@ -14,6 +14,7 @@ CONFIG_CRYPTO_SM4_GENERIC=3Dy CONFIG_DEBUG_INFO_BTF=3Dy CONFIG_DEBUG_INFO_BTF_MODULES=3Dn CONFIG_DUMMY=3Dy +CONFIG_ENABLE_DEFAULT_TRACERS=3Dy CONFIG_GENEVE=3Dm CONFIG_IFB=3Dy CONFIG_INET_DIAG=3Dy diff --git a/tools/testing/selftests/net/tunnel_drop_reasons.sh b/tools/tes= ting/selftests/net/tunnel_drop_reasons.sh new file mode 100755 index 000000000000..eb19967ae7dd --- /dev/null +++ b/tools/testing/selftests/net/tunnel_drop_reasons.sh @@ -0,0 +1,228 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Test the drop reasons reported by the generic tunnel RX path, +# ip_tunnel_rcv() and __ip6_tnl_rcv(). +# +# Two situations are checked, for both GRE and ip6gre: +# +# - the options carried by the packet do not match the tunnel +# configuration, which is reported as IP_TUNNEL_CFG_OPTS_MISMATCH. +# It is triggered here by configuring the receiver with 'iseq' or +# 'icsum' while the sender emits neither. +# +# - the sequence number of the packet is older than the one expected by +# the tunnel, which is reported as IP_TUNNEL_OLD_SEQ. It is +# triggered here by recreating the tunnel device on the sender, which +# resets its outgoing sequence number the same way a peer reboot +# would. +# +# A control case, where both endpoints agree on the options, makes sure +# that no tunnel drop reason is reported when packets are accepted. +# +# Drop reasons are read from the skb:kfree_skb tracepoint. A dedicated +# trace instance is used so that the test does not disturb, and is not +# disturbed by, anything else using the tracing facility. + +source lib.sh + +NS_SND=3D"" +NS_RCV=3D"" +TRACE_DIR=3D"" +TR=3D"" + +SND_V4=3D10.0.0.1 +RCV_V4=3D10.0.0.2 +SND_V6=3D2001:db8::1 +RCV_V6=3D2001:db8::2 +TUN_SND=3D192.168.1.1 +TUN_RCV=3D192.168.1.2 + +cleanup() +{ + if [ -n "$TR" ]; then + echo 0 > "$TR/events/skb/kfree_skb/enable" 2>/dev/null + rmdir "$TR" 2>/dev/null + fi + cleanup_all_ns +} + +trap cleanup EXIT + +setup_tracing() +{ + local dir + + for dir in /sys/kernel/tracing /sys/kernel/debug/tracing; do + if [ -f "$dir/trace" ]; then + TRACE_DIR=3D"$dir" + break + fi + done + [ -n "$TRACE_DIR" ] || return 1 + [ -d "$TRACE_DIR/instances" ] || return 1 + [ -e "$TRACE_DIR/events/skb/kfree_skb" ] || return 1 + + TR=3D"$TRACE_DIR/instances/tunnel_drop_reasons" + mkdir "$TR" 2>/dev/null || return 1 + echo 1 > "$TR/events/skb/kfree_skb/enable" || return 1 +} + +setup_ns_pair() +{ + cleanup_all_ns + setup_ns NS_SND NS_RCV + + ip link add veth_s netns "$NS_SND" type veth \ + peer name veth_r netns "$NS_RCV" + ip -n "$NS_SND" link set veth_s up + ip -n "$NS_RCV" link set veth_r up + + ip -n "$NS_SND" addr add "$SND_V4/24" dev veth_s + ip -n "$NS_RCV" addr add "$RCV_V4/24" dev veth_r + ip -n "$NS_SND" addr add "$SND_V6/64" dev veth_s nodad + ip -n "$NS_RCV" addr add "$RCV_V6/64" dev veth_r nodad +} + +# $1: namespace, $2: local, $3: remote, $4...: tunnel options +add_gre() +{ + local ns=3D$1 loc=3D$2 rem=3D$3 + + shift 3 + ip -n "$ns" link add gre_test type gre local "$loc" remote "$rem" "$@" + ip -n "$ns" link set gre_test up +} + +# $1: namespace, $2: local, $3: remote, $4...: tunnel options +add_ip6gre() +{ + local ns=3D$1 loc=3D$2 rem=3D$3 + + shift 3 + ip -n "$ns" link add gre_test type ip6gre local "$loc" remote "$rem" \ + "$@" + ip -n "$ns" link set gre_test up +} + +addr_tunnels() +{ + ip -n "$NS_SND" addr add "$TUN_SND/24" dev gre_test + ip -n "$NS_RCV" addr add "$TUN_RCV/24" dev gre_test +} + +send_traffic() +{ + ip netns exec "$NS_SND" ping -c 2 -W 1 "$TUN_RCV" >/dev/null 2>&1 + # Let the tracepoint records reach the trace buffer. + sleep 1 +} + +# $1: test name, $2: expected reason, empty if none is expected +check_reason() +{ + local name=3D$1 want=3D$2 count + + echo > "$TR/trace" + send_traffic + + if [ -n "$want" ]; then + count=3D$(grep -c "reason: $want" "$TR/trace") + if [ "$count" -gt 0 ]; then + RET=3D$ksft_pass + else + RET=3D$ksft_fail + fi + log_test "$name" "$count dropped" + else + count=3D$(grep -c "reason: IP_TUNNEL_" "$TR/trace") + if [ "$count" -eq 0 ]; then + RET=3D$ksft_pass + else + RET=3D$ksft_fail + fi + log_test "$name" "$count dropped" + fi +} + +test_opts_mismatch() +{ + local proto=3D$1 opt=3D$2 + local add=3Dadd_gre loc=3D$SND_V4 rem=3D$RCV_V4 + + if [ "$proto" =3D "ip6gre" ]; then + add=3Dadd_ip6gre + loc=3D$SND_V6 + rem=3D$RCV_V6 + fi + + setup_ns_pair + # The sender emits no option, the receiver expects one. + $add "$NS_SND" "$loc" "$rem" + $add "$NS_RCV" "$rem" "$loc" "$opt" + addr_tunnels + + check_reason "$proto: $opt option mismatch" \ + IP_TUNNEL_CFG_OPTS_MISMATCH +} + +test_old_seq() +{ + local proto=3D$1 + local add=3Dadd_gre loc=3D$SND_V4 rem=3D$RCV_V4 + + if [ "$proto" =3D "ip6gre" ]; then + add=3Dadd_ip6gre + loc=3D$SND_V6 + rem=3D$RCV_V6 + fi + + setup_ns_pair + $add "$NS_SND" "$loc" "$rem" oseq + $add "$NS_RCV" "$rem" "$loc" iseq + addr_tunnels + + # Raise the sequence number expected by the receiver, then reset the + # one used by the sender, as a peer reboot would do. + send_traffic + ip -n "$NS_SND" link del gre_test + $add "$NS_SND" "$loc" "$rem" oseq + ip -n "$NS_SND" addr add "$TUN_SND/24" dev gre_test + + check_reason "$proto: old sequence number" IP_TUNNEL_OLD_SEQ +} + +test_control() +{ + setup_ns_pair + add_gre "$NS_SND" "$SND_V4" "$RCV_V4" oseq ocsum + add_gre "$NS_RCV" "$RCV_V4" "$SND_V4" iseq icsum + addr_tunnels + + check_reason "gre: matching configuration (control)" "" +} + +if [ "$(id -u)" -ne 0 ]; then + echo "SKIP: need root" + exit "$ksft_skip" +fi + +if ! setup_tracing; then + echo "SKIP: could not set up a trace instance for skb:kfree_skb" + exit "$ksft_skip" +fi + +test_opts_mismatch gre iseq +test_opts_mismatch gre icsum +test_control +test_old_seq gre + +if [ -e /proc/sys/net/ipv6 ]; then + test_opts_mismatch ip6gre iseq + test_old_seq ip6gre +else + log_test_skip "ip6gre: iseq option mismatch" + log_test_skip "ip6gre: old sequence number" +fi + +exit "$EXIT_STATUS" --=20 2.47.3 From nobody Sat Sep 26 13:46:47 2026 Received: from mail-lj1-f170.google.com (mail-lj1-f170.google.com [209.85.208.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7D4AB3AB272 for ; Mon, 31 Aug 2026 21:52:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788213124; cv=none; b=buFFKb4EM2nrmKxKpi17Ji8jP/+UHWPqh/q9nrViwCFp9lfPvutHPzw1Tu6BhfA8LEB1uI27aJ0xwHAtTuVpUUbPLMJK/X0MpfTGw/I1+KJdxWWDnoMiJjxCyB22dnaNj31OSX3diZ15eQ/6IlG9K3OJ3W5yGHqKBpXo1Rflroc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788213124; c=relaxed/simple; bh=4ETydHIUMxlDO4oDu5fa8XhnlEwNHQHuV9lq4CMLD3A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=JYZCOtF4/HnJK34YiXxX+kbmRCtKsBvzXYS4yVbknJXXAFy1g+OgYratNQfTlxzDWVVtfTPaauWnF1v/xfNqlzt9q9dZxH0tGv9pFcV5mDb+y+/GS5vMUn+zzThEJ0A2jiZb4BZLI4LtX9WT0f5XNMjyDrZaKvNgYpm0cHvgPE8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=jHZbwL0H; arc=none smtp.client-ip=209.85.208.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="jHZbwL0H" Received: by mail-lj1-f170.google.com with SMTP id 38308e7fff4ca-39c8ee87f7eso1335871fa.3 for ; Mon, 31 Aug 2026 14:52:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788213117; x=1788817917; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=EtPySr7ef4Qsy5GLhJjPitHTdTOLF4vFl+f9aSnO9SE=; b=jHZbwL0HvVuHibw4GAJpS7PIwdU0a/wzpswxGqhhvz/Y4jf4jjxf6fmWD/Anccdx/b h+QUqMYwynjtF2merul3uK3XtfoL/ZpUCcMWyWOeWccW88jrWUHmNTa6xMzA9brpsjiu sCGVfcG0XkBHf5yFBun0HV5ubPErr8C43a+R1iIs5wKnsIpnYX//YPkdf1td8DNgPqYJ Ep/f6uSWcJ8Ps25Olyyeqo3alJ4heDQE59Mu4BsCJMrDaEXQWIPA+tdlGgxiJf3N5ew3 BXyGJHQiw9PnJrFpdX5EQxLZZr4sn5k4kkJvoRlPhLPX/hflqFabgzSsiMPtA2gSUuwR vnvA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788213117; x=1788817917; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=EtPySr7ef4Qsy5GLhJjPitHTdTOLF4vFl+f9aSnO9SE=; b=on1Uq6pmvuEa4lVWB7qVqScfTcj2+PMGqfMJcNO+5oWDle3s/OGFtP4T7jDmgSM6BU NXb8mHezlQIC4VP0rrBtsQvwZMNzqwVJ7O5gNNspazCdEMD9BZAZLnav1HGMRn4uZ/RL ddiCKhVX9a6YtSdPfJ2sBSMnIXgr+e0m1Yo9Jxnr5lwWzA7UZW2P0nCjeIwv5WJOaNe9 2l8o0py22d/nT448nbOxIw0re0KjGzd6bm+MyjJaTSkp3swMf1vlYky0QRtCk7Rpzy/C 5K9cYOf3/nOGVeM2CsNphZrv4i+54EkqTFmN78xOKfU2Z/aKEidvAcgIBRNNKaXM4ZiF FoPg== X-Forwarded-Encrypted: i=1; AKwUvBxDTFqJTt14yNenT96o/UIDU7zGocQyUFk9lftia/p6tKOtfrNnzqWArtUxK5GnTiY48kUToCUS+/2rQ8E=@vger.kernel.org X-Gm-Message-State: AFuF++nlmTriXPBpB1RwTY8+knv4RCoYsy5Ce2T2cG/QODb2qPbSGltF IU0zpv4OkUqZg2+YyQtzSlFpJsrXRtcbFYRzwC22ryvEB1llTpilK/XO X-Gm-Gg: AYBFou2FD002AHLaCUUJ4+gI7xiPiYE1eb2DCq6JVMTp9GZzpfb3xGIIMIWq6MBD/EU 0JBQuCs17bXe9IMX8YjsescHoBtnhRPdnff2UfHZ/VUaoZ4iqzjikbpzrFHUKcQkCIdZXZKfJJp 5O55CiqWlqOYHSuggGotUU7p9iG1FgYAjy1KqzMAGPMV9zG4+Br5/77uHgr6orwFBh3b5t1vHeU t4TT3yX7qNAyBkNAPO0sEXDRBYWam18R7QT+XvBv08tGcbvxUqaQaW2AgUnAdfbvL9ijFzFWTyW KxcmOZVtyoHzKBE814B0pggFWfT8ffabB1lsHsz4MzQENFNn+tBBjsGuUsrc6huSSg7o6JLEtGz J9mxKel1hWNzYOH7OpQZVofz+2Eg36XqtcekpqFbCvm/snd+tYqwzc8nx+I2c/lGWAUxcQ/i4Yx AlHz8ff1e//peE+UIouDE78bWvX7q0o7vKEWUl9lM7u1YQporsV4rKBGizkIn+T9cH875TGeBku 0uIKSe4YIsHCot4/b8i74k7zhnCvKPJ9g== X-Received: by 2002:a05:6512:3b8f:b0:5b5:e2f1:e6f9 with SMTP id 2adb3069b0e04-5b5e68bc823mr9495560e87.11.1788213117123; Mon, 31 Aug 2026 14:51:57 -0700 (PDT) Received: from dau-home-pc.. ([212.35.184.237]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b5e8a06a77sm2388782e87.48.2026.08.31.14.51.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Aug 2026 14:51:56 -0700 (PDT) From: Anton Danilov To: netdev@vger.kernel.org Cc: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , David Ahern , Simon Horman , Shuah Khan , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH net-next 04/11] gre: make gre_parse_header() report a drop reason Date: Tue, 1 Sep 2026 00:51:30 +0300 Message-ID: <20260831215137.549324-5-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260831215137.549324-1-littlesmilingcloud@gmail.com> References: <20260831215137.549324-1-littlesmilingcloud@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" gre_parse_header() returns -EINVAL for six different reasons and its callers turn that into a plain kfree_skb(). The only detail they could get so far was the csum_err flag, which none of them actually reads: both ip_gre and ip6_gre declare it, pass it in and then ignore it. Replace that dead output parameter with an enum skb_drop_reason one and let the two receive paths report what happened. Two reasons are added: - SKB_DROP_REASON_GRE_INVALID_HDR, for a header carrying an unsupported version or the routing bit, - SKB_DROP_REASON_GRE_CSUM, for a checksum error, next to the existing TCP_CSUM, UDP_CSUM, ICMP_CSUM and IP_CSUM. The header pull failures reuse SKB_DROP_REASON_HDR_TRUNC, which documents exactly this case, and gre_rcv() in the demux reuses pskb_may_pull_reason() and SKB_DROP_REASON_UNHANDLED_PROTO. A NULL reason keeps the meaning a NULL csum_err had: the caller is not interested in it and the checksum must not be verified. This matters for the ICMP error handlers, which only get a part of the original packet and must not drop it when the checksum does not validate. Tunnel lookup failures still report SKB_DROP_REASON_NOT_SPECIFIED here; they are addressed in the following patches. Assisted-by: Claude-Code:claude-opus-5 Signed-off-by: Anton Danilov --- include/net/dropreason-core.h | 9 +++++++ include/net/gre.h | 2 +- net/ipv4/gre_demux.c | 51 ++++++++++++++++++++++++++--------- net/ipv4/ip_gre.c | 6 ++--- net/ipv6/ip6_gre.c | 6 ++--- 5 files changed, 55 insertions(+), 19 deletions(-) diff --git a/include/net/dropreason-core.h b/include/net/dropreason-core.h index 40f94ecb912a..8efa682601f0 100644 --- a/include/net/dropreason-core.h +++ b/include/net/dropreason-core.h @@ -130,6 +130,8 @@ FN(RECURSION_LIMIT) \ FN(IP_TUNNEL_CFG_OPTS_MISMATCH) \ FN(IP_TUNNEL_OLD_SEQ) \ + FN(GRE_INVALID_HDR) \ + FN(GRE_CSUM) \ FNe(MAX) =20 /** @@ -622,6 +624,13 @@ enum skb_drop_reason { * numbering. */ SKB_DROP_REASON_IP_TUNNEL_OLD_SEQ, + /** + * @SKB_DROP_REASON_GRE_INVALID_HDR: the GRE header is invalid, e.g. + * an unsupported version or the routing bit is set. + */ + SKB_DROP_REASON_GRE_INVALID_HDR, + /** @SKB_DROP_REASON_GRE_CSUM: GRE checksum error */ + SKB_DROP_REASON_GRE_CSUM, /** * @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/include/net/gre.h b/include/net/gre.h index b55f67ecd2fc..a63f26c3f78e 100644 --- a/include/net/gre.h +++ b/include/net/gre.h @@ -33,7 +33,7 @@ int gre_add_protocol(const struct gre_protocol *proto, u8= version); int gre_del_protocol(const struct gre_protocol *proto, u8 version); =20 int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi, - bool *csum_err, __be16 proto, int nhs); + enum skb_drop_reason *reason, __be16 proto, int nhs); =20 static inline bool netif_is_gretap(const struct net_device *dev) { diff --git a/net/ipv4/gre_demux.c b/net/ipv4/gre_demux.c index 96fd7dc6d82d..598678f42ef5 100644 --- a/net/ipv4/gre_demux.c +++ b/net/ipv4/gre_demux.c @@ -58,26 +58,43 @@ EXPORT_SYMBOL_GPL(gre_del_protocol); =20 /* Fills in tpi and returns header length to be pulled. * Note that caller must use pskb_may_pull() before pulling GRE header. + * + * @reason is only written when the header is rejected, so the caller has + * to initialise it before the call. + * + * A NULL @reason means that the caller is not interested in the drop + * reason, and also that the checksum must not be verified. This is what + * the ICMP error handlers need, as they only get a part of the original + * packet. */ int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi, - bool *csum_err, __be16 proto, int nhs) + enum skb_drop_reason *reason, __be16 proto, int nhs) { const struct gre_base_hdr *greh; __be32 *options; int hdr_len; =20 - if (unlikely(!pskb_may_pull(skb, nhs + sizeof(struct gre_base_hdr)))) + if (unlikely(!pskb_may_pull(skb, nhs + sizeof(struct gre_base_hdr)))) { + if (reason) + *reason =3D SKB_DROP_REASON_HDR_TRUNC; return -EINVAL; + } =20 greh =3D (struct gre_base_hdr *)(skb->data + nhs); - if (unlikely(greh->flags & (GRE_VERSION | GRE_ROUTING))) + if (unlikely(greh->flags & (GRE_VERSION | GRE_ROUTING))) { + if (reason) + *reason =3D SKB_DROP_REASON_GRE_INVALID_HDR; return -EINVAL; + } =20 gre_flags_to_tnl_flags(tpi->flags, greh->flags); hdr_len =3D gre_calc_hlen(tpi->flags); =20 - if (!pskb_may_pull(skb, nhs + hdr_len)) + if (!pskb_may_pull(skb, nhs + hdr_len)) { + if (reason) + *reason =3D SKB_DROP_REASON_HDR_TRUNC; return -EINVAL; + } =20 greh =3D (struct gre_base_hdr *)(skb->data + nhs); tpi->proto =3D greh->protocol; @@ -87,8 +104,8 @@ int gre_parse_header(struct sk_buff *skb, struct tnl_ptk= _info *tpi, if (!skb_checksum_simple_validate(skb)) { skb_checksum_try_convert(skb, IPPROTO_GRE, null_compute_pseudo); - } else if (csum_err) { - *csum_err =3D true; + } else if (reason) { + *reason =3D SKB_DROP_REASON_GRE_CSUM; return -EINVAL; } =20 @@ -116,8 +133,11 @@ int gre_parse_header(struct sk_buff *skb, struct tnl_p= tk_info *tpi, =20 val =3D skb_header_pointer(skb, nhs + hdr_len, sizeof(_val), &_val); - if (!val) + if (!val) { + if (reason) + *reason =3D SKB_DROP_REASON_HDR_TRUNC; return -EINVAL; + } tpi->proto =3D proto; if ((*val & 0xF0) !=3D 0x40) hdr_len +=3D 4; @@ -132,8 +152,11 @@ int gre_parse_header(struct sk_buff *skb, struct tnl_p= tk_info *tpi, greh->protocol =3D=3D htons(ETH_P_ERSPAN2)) { struct erspan_base_hdr *ershdr; =20 - if (!pskb_may_pull(skb, nhs + hdr_len + sizeof(*ershdr))) + if (!pskb_may_pull(skb, nhs + hdr_len + sizeof(*ershdr))) { + if (reason) + *reason =3D SKB_DROP_REASON_HDR_TRUNC; return -EINVAL; + } =20 ershdr =3D (struct erspan_base_hdr *)(skb->data + nhs + hdr_len); tpi->key =3D cpu_to_be32(get_session_id(ershdr)); @@ -146,15 +169,19 @@ EXPORT_SYMBOL(gre_parse_header); static int gre_rcv(struct sk_buff *skb) { const struct gre_protocol *proto; + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; u8 ver; int ret; =20 - if (!pskb_may_pull(skb, 12)) + reason =3D pskb_may_pull_reason(skb, 12); + if (reason) goto drop; =20 ver =3D skb->data[1]&0x7f; - if (ver >=3D GREPROTO_MAX) + if (ver >=3D GREPROTO_MAX) { + reason =3D SKB_DROP_REASON_UNHANDLED_PROTO; goto drop; + } =20 rcu_read_lock(); proto =3D rcu_dereference(gre_proto[ver]); @@ -167,11 +194,11 @@ static int gre_rcv(struct sk_buff *skb) drop_nohandler: rcu_read_unlock(); dev_core_stats_rx_nohandler_inc(skb->dev); - kfree_skb(skb); + kfree_skb_reason(skb, SKB_DROP_REASON_UNHANDLED_PROTO); return NET_RX_DROP; drop: dev_core_stats_rx_dropped_inc(skb->dev); - kfree_skb(skb); + kfree_skb_reason(skb, reason); return NET_RX_DROP; } =20 diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 82309efd417e..1894c5746a73 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -439,8 +439,8 @@ static int ipgre_rcv(struct sk_buff *skb, const struct = tnl_ptk_info *tpi, =20 static int gre_rcv(struct sk_buff *skb) { + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; struct tnl_ptk_info tpi; - bool csum_err =3D false; int hdr_len; =20 #ifdef CONFIG_NET_IPGRE_BROADCAST @@ -451,7 +451,7 @@ static int gre_rcv(struct sk_buff *skb) } #endif =20 - hdr_len =3D gre_parse_header(skb, &tpi, &csum_err, htons(ETH_P_IP), 0); + hdr_len =3D gre_parse_header(skb, &tpi, &reason, htons(ETH_P_IP), 0); if (hdr_len < 0) goto drop; =20 @@ -469,7 +469,7 @@ static int gre_rcv(struct sk_buff *skb) icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); drop: dev_core_stats_rx_dropped_inc(skb->dev); - kfree_skb(skb); + kfree_skb_reason(skb, reason); return 0; } =20 diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 69c51f1a5bf0..736eefdb528f 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -569,11 +569,11 @@ static int ip6erspan_rcv(struct sk_buff *skb, =20 static int gre_rcv(struct sk_buff *skb) { + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; struct tnl_ptk_info tpi; - bool csum_err =3D false; int hdr_len; =20 - hdr_len =3D gre_parse_header(skb, &tpi, &csum_err, htons(ETH_P_IPV6), 0); + hdr_len =3D gre_parse_header(skb, &tpi, &reason, htons(ETH_P_IPV6), 0); if (hdr_len < 0) goto drop; =20 @@ -594,7 +594,7 @@ static int gre_rcv(struct sk_buff *skb) icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0); drop: dev_core_stats_rx_dropped_inc(skb->dev); - kfree_skb(skb); + kfree_skb_reason(skb, reason); return 0; } =20 --=20 2.47.3 From nobody Sat Sep 26 13:46:47 2026 Received: from mail-lj1-f172.google.com (mail-lj1-f172.google.com [209.85.208.172]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 506DE3B47CA for ; Mon, 31 Aug 2026 21:52:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788213128; cv=none; b=ecQN80aEAWwOfMeS1sXqWlQ7Udtl2kWc5Gue+qnesUqZwWcClWCil7oet7zcDalFcwWBMegbLZU3v9OOOojE6Au6KoudLHRMzkcUIQV/YATxu9+AktHrKeK2D5qSBdtI3n+MWIE/V2s3wJivMjd77N0dyUYwgjszldRfrztj8fQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788213128; c=relaxed/simple; bh=Vqr2T+pAGvS4B2S/igN6uZz1bzPoPaAuFk3laQUpdbA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ThPwXgj2vwbkuhGVoMs8YEb+V+hANuBR6hbzhQqI8J6p28kqwuAnouBY8WQ7BsxZkAngzNdG3MiuOu8TpP+yE8REljb0g5yLR9RMWrlDSPlGZLO9/KQlDOism7KYGpplmZ5gVHr7+Gjfs2sPBukodc81i6ga9+4qR+O63YdWT24= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=o8ymK2Kr; arc=none smtp.client-ip=209.85.208.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="o8ymK2Kr" Received: by mail-lj1-f172.google.com with SMTP id 38308e7fff4ca-3a12ffc112cso3663281fa.0 for ; Mon, 31 Aug 2026 14:52:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788213118; x=1788817918; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=rk6J7+EqI01O7WAeHSssesqmqhnxRq/0S1+yQRl3tCs=; b=o8ymK2Kr09jIfBw8ePUnWIAe79SHtvHP65N9uvN4hXX/zwtUuPWshh1k729y48QUod 8RdCV/eNabxQ6JrVTYMoij+aNRRG5gTgtwO7rpvyYJNaeip98TMH9L1snEzVE+PkSKIk ARu/JPTgnqbXcCTdw7Z++YQv4M5YBfPoziZZ58cGyp/a3UVQocX7xtUJ6LsyVdSbvLzE 09zJM3bo8Pa+sglARW/APU0wQdEyi6U/lSoK7IYe4RI+ERstUP7YFBgwmLCUoAubT5dz 75bNrixlIV2HWLp81bPFbvYdo8Wx8ogGB1wdZTGf6xQIU6gvYvS7FMIjK0w67uw/efJI fGuQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788213118; x=1788817918; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=rk6J7+EqI01O7WAeHSssesqmqhnxRq/0S1+yQRl3tCs=; b=BlJkyEaNgXUjNUu8UgokamQoTj7zSH9PFD3WFZawpPeh4xbAnluybTv3pqA212Xtat kDEnCqNLNJaiwZsFF3w3RKd2w/zDWrtt7+8Pwe5i3EHpk7WZ9SVsSUE+9AAJcF51Ck1/ SodCEmrjeRehjLjLQvR2tivlwMoJ3JFI0PDjY2eAWYoODbOWQYIHIP7MA7P5QPgd1pne Y43ibb8eMsqjufkvKVW8WP4c1tndqgYnxUgNdqQPK551djVfoiIaaYM/mTEIY/9eqdtH 5/6VacG7EXEjGkyc4zqNmF2qp1CT/6y5gbAMs6ZE+jm6x2FNIIRPg9TGCZL0Qv/hLT16 avFg== X-Forwarded-Encrypted: i=1; AKwUvBw95x//w19Axd1F00JILiMb+02rlPl0+1dY1RQM1cisfa7bqR1Qm0kT0iqy52Ba4H+fU/ggK34TcexIBh4=@vger.kernel.org X-Gm-Message-State: AFuF++myEVS+/UeyvFc5PhN2BNzxNnGQCd/ynLiITw4NZltJdScT+YVV 6jJaSH1rETBVEu84Nr0tD9Wc6s73KNSQ5iaN0f+XFs0quW7IiUoH68tY X-Gm-Gg: AYBFou0L5PvztXOOQpDtUi4pz/AJi1JnFkzVs4CbVMVVTDNrMNNejHoW7/bwWxWXoy6 trEzWqXW7UzbK3R/ssqzqKtZ0yKEo+ch+TUc66xhsljVLsCHJDc7ty6XluzWn4nDp/20g0wGhlv dWL8APZ95194+idDlnLrbPVOEQG5/XyJWn15m20+wJU1IWVbQODPfQwb32Ihpd0ktVpv8f/yLXL K3sosqNcQVMehFJa4k29NHoQZzunx5D9EKyLdHbj5eA9OvcgEg/d5XBeg6EmWPbFZRrDJr2q/wP OISVtlqT7Z4sY7k/fcZYYEwE7bDYqqFVC79P808yG9ycnYPw7TPVrZl96OKTxfzF3Fxvy07MBcc VbdwQpMlbkHf5FI0Nb3Xob7AbQ4DeLbEz9Rb+vE7TyB/pE57m+OLuZN3UB4Jdu+ZC3gNxWwtQEK YiNcceTtZfGsoD3WaNbO4CO4QbimZm/SFIsxttWQEByz5Eq60Fx7vNLhMZ1zyS8+XTijB3+Odp+ Fxq0m+OQBP7n5tVQxAqt5ffW3QRhnbsPw== X-Received: by 2002:a05:6512:3b0d:b0:5b4:74c4:4723 with SMTP id 2adb3069b0e04-5b5ff425e99mr293164e87.9.1788213118262; Mon, 31 Aug 2026 14:51:58 -0700 (PDT) Received: from dau-home-pc.. ([212.35.184.237]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b5e8a06a77sm2388782e87.48.2026.08.31.14.51.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Aug 2026 14:51:57 -0700 (PDT) From: Anton Danilov To: netdev@vger.kernel.org Cc: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , David Ahern , Simon Horman , Shuah Khan , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH net-next 05/11] ip_gre: add drop reasons to the RX path Date: Tue, 1 Sep 2026 00:51:31 +0300 Message-ID: <20260831215137.549324-6-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260831215137.549324-1-littlesmilingcloud@gmail.com> References: <20260831215137.549324-1-littlesmilingcloud@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" A packet that reaches gre_rcv() and does not belong to any tunnel is dropped, after an ICMP port unreachable is sent back, with a plain kfree_skb(). This is the GRE counterpart of a UDP packet hitting no socket, and by far the most common way a GRE packet is dropped on receive, yet nothing tells it apart from a malformed one. Add SKB_DROP_REASON_GRE_TUNNEL_NOT_FOUND for it, in the spirit of the existing SKB_DROP_REASON_VXLAN_VNI_NOT_FOUND, and report it from erspan_rcv() and __ipgre_rcv() through a new output parameter, so that a failed lookup is not reported the same way as a header that could not be pulled or as a metadata allocation failure. The header pull failures reuse SKB_DROP_REASON_HDR_TRUNC and the metadata allocation failures reuse SKB_DROP_REASON_NOMEM. Assisted-by: Claude-Code:claude-opus-5 Signed-off-by: Anton Danilov --- include/net/dropreason-core.h | 6 ++++++ net/ipv4/ip_gre.c | 37 +++++++++++++++++++++++------------ 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/include/net/dropreason-core.h b/include/net/dropreason-core.h index 8efa682601f0..d1fb52c1b0cb 100644 --- a/include/net/dropreason-core.h +++ b/include/net/dropreason-core.h @@ -132,6 +132,7 @@ FN(IP_TUNNEL_OLD_SEQ) \ FN(GRE_INVALID_HDR) \ FN(GRE_CSUM) \ + FN(GRE_TUNNEL_NOT_FOUND) \ FNe(MAX) =20 /** @@ -631,6 +632,11 @@ enum skb_drop_reason { SKB_DROP_REASON_GRE_INVALID_HDR, /** @SKB_DROP_REASON_GRE_CSUM: GRE checksum error */ SKB_DROP_REASON_GRE_CSUM, + /** + * @SKB_DROP_REASON_GRE_TUNNEL_NOT_FOUND: no GRE tunnel found for the + * endpoints and the key the packet carries. + */ + SKB_DROP_REASON_GRE_TUNNEL_NOT_FOUND, /** * @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_gre.c b/net/ipv4/ip_gre.c index 1894c5746a73..4d9bb6d186ae 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -265,7 +265,7 @@ static bool is_erspan_type1(int gre_hdr_len) } =20 static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi, - int gre_hdr_len) + int gre_hdr_len, enum skb_drop_reason *reason) { struct net *net =3D dev_net(skb->dev); struct metadata_dst *tun_dst =3D NULL; @@ -289,8 +289,10 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_= ptk_info *tpi, iph->saddr, iph->daddr, 0); } else { if (unlikely(!pskb_may_pull(skb, - gre_hdr_len + sizeof(*ershdr)))) + gre_hdr_len + sizeof(*ershdr)))) { + *reason =3D SKB_DROP_REASON_HDR_TRUNC; return PACKET_REJECT; + } =20 ershdr =3D (struct erspan_base_hdr *)(skb->data + gre_hdr_len); ver =3D ershdr->ver; @@ -306,8 +308,10 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_= ptk_info *tpi, else len =3D gre_hdr_len + erspan_hdr_len(ver); =20 - if (unlikely(!pskb_may_pull(skb, len))) + if (unlikely(!pskb_may_pull(skb, len))) { + *reason =3D SKB_DROP_REASON_HDR_TRUNC; return PACKET_REJECT; + } =20 if (__iptunnel_pull_header(skb, len, @@ -327,8 +331,10 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_= ptk_info *tpi, =20 tun_dst =3D ip_tun_rx_dst(skb, flags, tun_id, sizeof(*md)); - if (!tun_dst) + if (!tun_dst) { + *reason =3D SKB_DROP_REASON_NOMEM; return PACKET_REJECT; + } =20 /* MUST set options_len before referencing options */ info =3D &tun_dst->u.tun_info; @@ -356,15 +362,17 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl= _ptk_info *tpi, ip_tunnel_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error); return PACKET_RCVD; } + *reason =3D SKB_DROP_REASON_GRE_TUNNEL_NOT_FOUND; return PACKET_REJECT; =20 drop: - kfree_skb(skb); + kfree_skb_reason(skb, SKB_DROP_REASON_HDR_TRUNC); return PACKET_RCVD; } =20 static int __ipgre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi, - struct ip_tunnel_net *itn, int hdr_len, bool raw_proto) + struct ip_tunnel_net *itn, int hdr_len, bool raw_proto, + enum skb_drop_reason *reason) { struct metadata_dst *tun_dst =3D NULL; const struct iphdr *iph; @@ -400,22 +408,25 @@ static int __ipgre_rcv(struct sk_buff *skb, const str= uct tnl_ptk_info *tpi, =20 tun_id =3D key32_to_tunnel_id(tpi->key); tun_dst =3D ip_tun_rx_dst(skb, flags, tun_id, 0); - if (!tun_dst) + if (!tun_dst) { + *reason =3D SKB_DROP_REASON_NOMEM; return PACKET_REJECT; + } } =20 ip_tunnel_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error); return PACKET_RCVD; } + *reason =3D SKB_DROP_REASON_GRE_TUNNEL_NOT_FOUND; return PACKET_NEXT; =20 drop: - kfree_skb(skb); + kfree_skb_reason(skb, SKB_DROP_REASON_HDR_TRUNC); return PACKET_RCVD; } =20 static int ipgre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi, - int hdr_len) + int hdr_len, enum skb_drop_reason *reason) { struct net *net =3D dev_net(skb->dev); struct ip_tunnel_net *itn; @@ -426,13 +437,13 @@ static int ipgre_rcv(struct sk_buff *skb, const struc= t tnl_ptk_info *tpi, else itn =3D net_generic(net, ipgre_net_id); =20 - res =3D __ipgre_rcv(skb, tpi, itn, hdr_len, false); + res =3D __ipgre_rcv(skb, tpi, itn, hdr_len, false, reason); if (res =3D=3D PACKET_NEXT && tpi->proto =3D=3D htons(ETH_P_TEB)) { /* ipgre tunnels in collect metadata mode should receive * also ETH_P_TEB traffic. */ itn =3D net_generic(net, ipgre_net_id); - res =3D __ipgre_rcv(skb, tpi, itn, hdr_len, true); + res =3D __ipgre_rcv(skb, tpi, itn, hdr_len, true, reason); } return res; } @@ -457,12 +468,12 @@ static int gre_rcv(struct sk_buff *skb) =20 if (unlikely(tpi.proto =3D=3D htons(ETH_P_ERSPAN) || tpi.proto =3D=3D htons(ETH_P_ERSPAN2))) { - if (erspan_rcv(skb, &tpi, hdr_len) =3D=3D PACKET_RCVD) + if (erspan_rcv(skb, &tpi, hdr_len, &reason) =3D=3D PACKET_RCVD) return 0; goto out; } =20 - if (ipgre_rcv(skb, &tpi, hdr_len) =3D=3D PACKET_RCVD) + if (ipgre_rcv(skb, &tpi, hdr_len, &reason) =3D=3D PACKET_RCVD) return 0; =20 out: --=20 2.47.3 From nobody Sat Sep 26 13:46:47 2026 Received: from mail-lf1-f47.google.com (mail-lf1-f47.google.com [209.85.167.47]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CF9433AFCFA for ; Mon, 31 Aug 2026 21:52:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788213125; cv=none; b=ON1uPsCOFMARX0Hjb3PA04i7bmUneOy51+oIMeqjzLyGitBYLdj+Oqt43AK7HIOLNl+8toZGai7hv/ok2m7dHOKujFmIiNN3ZQpp123LVOcy4+rTD2UgSdkZrjagrQZ6keVpneNXkag+ke1eEIZysl8v4dFVy1VyH5bM3NcLhyc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788213125; c=relaxed/simple; bh=GImSaBburXI+fSPmhv1GLTsPcvIOT1rc2hIuZWzMLxI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=JIo62iS81UVAx14xO6pWo2AjOKoBxbjfztyGhdHP/W9vRIm/sQ5r0uPTvxw/Su2juZaGC3SK6u8Y3wSFUQFfha7m1/RbPsDnyzrKj2Xp7jjB+/+9Zhc9cXcXLYu0jZVQmp5gxa7OCKIzcNuNtfJ8cOwjcMRxnOH4Xy3pHMK/Ecw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=KrX7zYjd; arc=none smtp.client-ip=209.85.167.47 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="KrX7zYjd" Received: by mail-lf1-f47.google.com with SMTP id 2adb3069b0e04-5b4ae3e201cso3726852e87.2 for ; Mon, 31 Aug 2026 14:52:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788213119; x=1788817919; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=JLqppsKFYm25VyfvfGmhK0W3JzFpvK1MwZIK8QKSzOQ=; b=KrX7zYjd+cs0rzJwjfdWX2eaZTMX65rltXU4f7PSDBTrEMYONt6QZK/rXvvHBtWiM3 cezxu6pEBm7dja/cbQoaJ+uBARVDh32bXnyg7mFU/79pD6I+XDIJTN0mTLirkznr0e5D WPFSBfTlyVS3mDUbV3AUDwdDilE3ZCt6mPqe2Jfthj7ygndFmxR/qLJIJK4hRcd+Gpw/ VfUBREJC2CFs1SA2EozpQorxNtSkqOMNn/Jx0VZHZi1ttB3PFt7YcQWEgEAbzdC5U3w9 XE/yB4+Gv1XNFYED7v8wwb6XdoiDXi5D45PKm49JRjx0LYU/EFLD01+hCyj/h1yYo7f7 HPwQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788213119; x=1788817919; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=JLqppsKFYm25VyfvfGmhK0W3JzFpvK1MwZIK8QKSzOQ=; b=aFo8A5UB94Bhv/t4ar3XXdl19GIcx4bCP2228rj6jbED+fq+4qfs0JE2ptWMoO1FRk VkIv/LKtiSgg3nS11L8nDvkfUqE5hn0zjjeQnQqYWObcngqsxQXIy7nPtpEVtZZa+xPw u7J3UIDZprsMfFo92gF3kZPXOX5++9ovFyBT0EWvO+EFsiLGdeF6cjkTZB730AKCHzU/ BYcBk2ALVTjDkPs7PX+Vj+bp892lFydSiSPaUUfhmO/83X7bvhN2QaHVYR/wi+wXEMC5 DV3jRycwvaEMuROt6AiDXUgx8LQjouLYFzuJS9g7KwkzaQL+nznvRDtsRO+bajME6I26 voxg== X-Forwarded-Encrypted: i=1; AKwUvBy6SSaIqOXTj7DmCGi6fgiI/Dr7j9Eo0WvZthZLoPF/lmQFXuLOdeQj7mtJItVAxyXiSFOGUHVIdGwWWKU=@vger.kernel.org X-Gm-Message-State: AFuF++nZqK87w3YSBdXDmTmFEYwZ4gBPWMLdxvfr0v78sgpDDiXALhjX XjcvySxM/jGVowMHCXTO+jFEbeDgB08tSpAWAvTbaGhEn4cOMxB/ako/ X-Gm-Gg: AYBFou0oDCAyzb+jPbAl5Y9+UHESYhfiGiZRgWuzMgCZWjFp93tLwnDAfOqUoWxACNz bnnA9N+iPM6A1ouqfZzdY+UWwk9v/9rJgbN0KbeHS6Nwdeco84DeYJLVac3PYYcSnhAIEHUG/nI YkmKAR56G37K3LQ61qZmzehF6gvaJ8mDqZ/SLv2mw4YEzJLKFJMLRF98bJmoVnM6XnacFQJmqqZ hlOoIy7dtXDCF6F0bHd2ffmM5FwLvIUDpaZoDMtQnMwS3VZ6LL3mbmYyVb0merhhmGauc0Nk7XR y0Gj+4xXEI5/w5aJJBP3oZtkfR6BzsTFbflHXG2dFgp2pO/rVAjNQwtpz1ETLLffX51vo090XKw HmsSLXQQBUzscEgCNc2Co+XIeUu+XD6nT6cvC771L5Nh1Ilx0U8+RAS1UzA9H8Edmnv9fji5hGK yefUvsmvtYKaEsaKpL+/IT1q+j7vAY+f2R7Zsybmd12Jr3NmFRSmnl6xh5ufTtQzq7oH9rYxD30 Ks7Eo3pjdfl38kCe+4iVcd/qjSLccag2Q== X-Received: by 2002:a05:6512:6288:b0:5b0:15b1:3d5d with SMTP id 2adb3069b0e04-5b5e6902f5fmr9592721e87.22.1788213119500; Mon, 31 Aug 2026 14:51:59 -0700 (PDT) Received: from dau-home-pc.. ([212.35.184.237]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b5e8a06a77sm2388782e87.48.2026.08.31.14.51.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Aug 2026 14:51:58 -0700 (PDT) From: Anton Danilov To: netdev@vger.kernel.org Cc: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , David Ahern , Simon Horman , Shuah Khan , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH net-next 06/11] ip6_gre: add drop reasons to the RX path Date: Tue, 1 Sep 2026 00:51:32 +0300 Message-ID: <20260831215137.549324-7-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260831215137.549324-1-littlesmilingcloud@gmail.com> References: <20260831215137.549324-1-littlesmilingcloud@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 --- 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; } =20 -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 struc= t tnl_ptk_info *tpi) tun_id =3D key32_to_tunnel_id(tpi->key); =20 tun_dst =3D ipv6_tun_rx_dst(skb, flags, tun_id, 0); - if (!tun_dst) + if (!tun_dst) { + *reason =3D SKB_DROP_REASON_NOMEM; return PACKET_REJECT; + } =20 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 stru= ct tnl_ptk_info *tpi) return PACKET_RCVD; } =20 + *reason =3D SKB_DROP_REASON_GRE_TUNNEL_NOT_FOUND; return PACKET_REJECT; } =20 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; =20 - if (unlikely(!pskb_may_pull(skb, sizeof(*ershdr)))) + if (unlikely(!pskb_may_pull(skb, sizeof(*ershdr)))) { + *reason =3D SKB_DROP_REASON_HDR_TRUNC; return PACKET_REJECT; + } =20 ipv6h =3D ipv6_hdr(skb); ershdr =3D (struct erspan_base_hdr *)skb->data; @@ -510,13 +517,17 @@ static int ip6erspan_rcv(struct sk_buff *skb, if (tunnel) { int len =3D erspan_hdr_len(ver); =20 - if (unlikely(!pskb_may_pull(skb, len))) + if (unlikely(!pskb_may_pull(skb, len))) { + *reason =3D SKB_DROP_REASON_HDR_TRUNC; return PACKET_REJECT; + } =20 if (__iptunnel_pull_header(skb, len, htons(ETH_P_TEB), - false, false) < 0) + false, false) < 0) { + *reason =3D SKB_DROP_REASON_HDR_TRUNC; return PACKET_REJECT; + } =20 if (tunnel->parms.collect_md) { struct erspan_metadata *pkt_md, *md; @@ -532,8 +543,10 @@ static int ip6erspan_rcv(struct sk_buff *skb, =20 tun_dst =3D ipv6_tun_rx_dst(skb, flags, tun_id, sizeof(*md)); - if (!tun_dst) + if (!tun_dst) { + *reason =3D SKB_DROP_REASON_NOMEM; return PACKET_REJECT; + } =20 /* MUST set options_len before referencing options */ info =3D &tun_dst->u.tun_info; @@ -564,6 +577,7 @@ static int ip6erspan_rcv(struct sk_buff *skb, return PACKET_RCVD; } =20 + *reason =3D SKB_DROP_REASON_GRE_TUNNEL_NOT_FOUND; return PACKET_REJECT; } =20 @@ -577,17 +591,19 @@ static int gre_rcv(struct sk_buff *skb) if (hdr_len < 0) goto drop; =20 - if (iptunnel_pull_header(skb, hdr_len, tpi.proto, false)) + if (iptunnel_pull_header(skb, hdr_len, tpi.proto, false)) { + reason =3D SKB_DROP_REASON_HDR_TRUNC; goto drop; + } =20 if (unlikely(tpi.proto =3D=3D htons(ETH_P_ERSPAN) || tpi.proto =3D=3D htons(ETH_P_ERSPAN2))) { - if (ip6erspan_rcv(skb, &tpi, hdr_len) =3D=3D PACKET_RCVD) + if (ip6erspan_rcv(skb, &tpi, hdr_len, &reason) =3D=3D PACKET_RCVD) return 0; goto out; } =20 - if (ip6gre_rcv(skb, &tpi) =3D=3D PACKET_RCVD) + if (ip6gre_rcv(skb, &tpi, &reason) =3D=3D PACKET_RCVD) return 0; =20 out: --=20 2.47.3 From nobody Sat Sep 26 13:46:47 2026 Received: from mail-lf1-f53.google.com (mail-lf1-f53.google.com [209.85.167.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 499E33B3894 for ; Mon, 31 Aug 2026 21:52:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788213128; cv=none; b=rhRWe6m3KxwYQTDlGjWOa/zjGvZgtBvpgucHUhhLVf0u6KV2zIkvXhowyf7lp/tnNG2uSAWNjGDQjX8N/u+ordYTDPT+nmWwPH7PAv1kYomw7StwIgMfUxe0AG+JwedpSvlFveXnKsX9iviYhUt9kBt/kTOQ3Pw8dN0E+8bUdcI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788213128; c=relaxed/simple; bh=YuTeDlB5rSGQjCGg0nhug/A5mS/4NUh11W33+NvMTeI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=P4uABlrYZi6jVQI6Qn/BIMEAjmYgWfiQ8OcQA+yxdOFxFGUiZUUl7eNaG8vDjeIe4L0aYm7brCimh577GAIr9oKQKVlT4XgfcJujyDgY1w9FR4wwRpf5mLGUABORdOyHE6VH243DTLqgQLbvChd/EHTOy3V+CBl68rZm09oBoFQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=MjhmwFaR; arc=none smtp.client-ip=209.85.167.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="MjhmwFaR" Received: by mail-lf1-f53.google.com with SMTP id 2adb3069b0e04-5b5607bd3b5so3646233e87.3 for ; Mon, 31 Aug 2026 14:52:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788213121; x=1788817921; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=N3b1QazDuG4xzv4W7Y1bzZmafsmvUHp3dVsi9T+Ml1A=; b=MjhmwFaRxYAvYIWJsf6j0XmbfbkCHQnWXCzAfNge6i+m/SXHRtjmGuJfEzGNQ0Rgnm PxA1cCeDJloqh5W1EQSu7zGkgBQGy3O6aPofbHGAsTCHkD40UDsnKm/GAWVpNGg8Igz/ iauwHokC1pdmvpfxkhC58kjprU9nhJopkAHCQhNqHOZKz/i5LJXseytLmE4HBeW974JI UAK7MLFfivGFfzZCWbBWF3TofzEhFvl75hak4tGGEcgaEuH2SDCFilJ8gBxoEl1XWWpt KHUrQ+vgHITNuaI37YbBlBcXWNX2ntzpkAOf9RH0TeGEWZxCNxnEOuhDrSdUGUdvzl0J yYJA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788213121; x=1788817921; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=N3b1QazDuG4xzv4W7Y1bzZmafsmvUHp3dVsi9T+Ml1A=; b=Hjo0w3wlF+qY0x+p+0Bkl0fUjxasN2A043cxNEWVDMU4H8E57lPzjc/x/wQCWksaLQ IUuEVxB4YZXmE1r3qERmG9Dvb7bOWiPHlYyy3RtRZI9jBQ/O6T7z2tskIMToWMiJkajJ 4VuKnYzUiCr4Dp0XlbFy9SpltYpVKvEh4FIWcwvG/nhuvvFjIPhGBgKMZEA795/iTVCb wA9GEKc7/KBo5Yd2VyQEtIfgIi6m5fOjoQzCWVm3MmdxRSwKV7rL4Wve2YGIbA92ckqB Cr/MDklUeeFwFckjjCSL+wGxu6Vbx75PniJPGJ7yOd7iJMcePIIkrN21Di04VRU6gU36 8b0A== X-Forwarded-Encrypted: i=1; AKwUvBxu+QNQGsln23hDlKihnc+N5+ScrlB0BNqPTZsR2CGz8Fyd1ZlA5cOgHnKGNOktoX59hF6uqjcygPp9Q4Y=@vger.kernel.org X-Gm-Message-State: AFuF++kLt+nzfA6+GJbNhwQJzz9lbC1pvFawYykXshn6BMfdKQe3W/3b 0aXHyFNAiat/nnYdBwQ9dpaGs+8R3hC7m8QliKke3YTHZw1hAg/g9gUI X-Gm-Gg: AYBFou0U0sfiR3KfsgrpMp2V9LVLA0pMT4I7iI6FWnyfipcxTKm5IvaTcT3L0Z1PQhK 5plcZKO1D+Y8CiFyTwdiauI3h6AI+/N1JgQcihKXPiHmkARHIKTBoJeOJsgekLVmtKEvw8QnGjl Tu8PFnq3l+qowuGj2jSM6VfD9R3FsL4LDABZOGPBq0q0Lpu65gSVCeD8P6r+7CPKWeaV2avYQUU Qp4NdCptj1lMfoaQoezJ3e4iebVwHuZeCg3BnI75yB7vGyIHxzZkNaFgE6iVx2XggBTMOzXz+Lb EEdR0aaapi1WR2LTTeweTgiQWA+4BII1CsIQrbuvRQMmUtdRXrI2iT1iwkh4fsiCeHnsOxPG/YI Qm2ghSRjz4sqes0+RTUyvdTMPlmudBEN5n0tlJ77AUuSZDhuDsVqTeFDuwlHlj5YO3JdUfXyxAN Hw8RzgvDDSoMdd9nYv7opxv+98GV+X7SLEwq0EcJh8ibtP4ALQQ2Qe8swY7d4I0K2oCwPYlJmc0 7cJBtOczbCoSGgZPOzhlC0KJwpFpkZAWXZxKW1I2zAT X-Received: by 2002:a05:6512:3c8a:b0:5b0:22a6:6b13 with SMTP id 2adb3069b0e04-5b5e684ae6bmr9361502e87.0.1788213121068; Mon, 31 Aug 2026 14:52:01 -0700 (PDT) Received: from dau-home-pc.. ([212.35.184.237]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b5e8a06a77sm2388782e87.48.2026.08.31.14.51.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Aug 2026 14:52:00 -0700 (PDT) From: Anton Danilov To: netdev@vger.kernel.org Cc: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , David Ahern , Simon Horman , Shuah Khan , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH net-next 07/11] selftests: net: cover the GRE specific drop reasons Date: Tue, 1 Sep 2026 00:51:33 +0300 Message-ID: <20260831215137.549324-8-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260831215137.549324-1-littlesmilingcloud@gmail.com> References: <20260831215137.549324-1-littlesmilingcloud@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Extend the tunnel drop reason test with the reasons added to the GRE receive path: - two endpoints configured with different keys make the tunnel lookup on the receiver fail, which is reported as GRE_TUNNEL_NOT_FOUND, - setting the routing bit of the GRE header is reported as GRE_INVALID_HDR, and announcing GRE version 1, which has no handler unless PPTP is built in, is reported as UNHANDLED_PROTO. The last two corrupt the header of the received packets with tc pedit and are skipped when the ingress qdisc or the pedit action are not available. SKB_DROP_REASON_GRE_CSUM is not covered: veth hands the packets over with CHECKSUM_UNNECESSARY, so the GRE checksum is never validated and the reason cannot be reached without crafting the packets. Assisted-by: Claude-Code:claude-opus-5 Signed-off-by: Anton Danilov --- .../selftests/net/tunnel_drop_reasons.sh | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/tools/testing/selftests/net/tunnel_drop_reasons.sh b/tools/tes= ting/selftests/net/tunnel_drop_reasons.sh index eb19967ae7dd..aad003f0efe5 100755 --- a/tools/testing/selftests/net/tunnel_drop_reasons.sh +++ b/tools/testing/selftests/net/tunnel_drop_reasons.sh @@ -20,6 +20,17 @@ # A control case, where both endpoints agree on the options, makes sure # that no tunnel drop reason is reported when packets are accepted. # +# The GRE specific reasons are checked as well: +# +# - a packet that matches no tunnel is reported as +# GRE_TUNNEL_NOT_FOUND. It is triggered here by giving the two +# endpoints different keys. +# +# - a header with the routing bit set is reported as GRE_INVALID_HDR, +# and a header announcing a GRE version nobody handles is reported as +# UNHANDLED_PROTO. Both are triggered by corrupting the GRE header +# on ingress with tc pedit, and are skipped if that is not available. +# # Drop reasons are read from the skb:kfree_skb tracepoint. A dedicated # trace instance is used so that the test does not disturb, and is not # disturbed by, anything else using the tracing facility. @@ -202,6 +213,47 @@ test_control() check_reason "gre: matching configuration (control)" "" } =20 +# Corrupt one field of the GRE header of every IPv4 packet received by +# the receiver. $1 is a tc pedit munge expression, with offsets counted +# from the start of the IPv4 header. +corrupt_gre_header() +{ + ip netns exec "$NS_RCV" tc qdisc add dev veth_r ingress || return 1 + ip netns exec "$NS_RCV" tc filter add dev veth_r ingress \ + protocol ip matchall action pedit ex munge "$@" || return 1 +} + +test_tunnel_not_found() +{ + setup_ns_pair + # The two endpoints use different keys, so the lookup on the + # receiver finds no tunnel for the incoming packets. + add_gre "$NS_SND" "$SND_V4" "$RCV_V4" okey 1 ikey 1 + add_gre "$NS_RCV" "$RCV_V4" "$SND_V4" okey 2 ikey 2 + addr_tunnels + + check_reason "gre: tunnel not found" GRE_TUNNEL_NOT_FOUND +} + +# $1: test name, $2: expected reason, $3...: tc pedit munge expression +test_corrupted_header() +{ + local name=3D$1 want=3D$2 + + shift 2 + setup_ns_pair + add_gre "$NS_SND" "$SND_V4" "$RCV_V4" + add_gre "$NS_RCV" "$RCV_V4" "$SND_V4" + addr_tunnels + + if ! corrupt_gre_header "$@" 2>/dev/null; then + log_test_skip "$name" + return + fi + + check_reason "$name" "$want" +} + if [ "$(id -u)" -ne 0 ]; then echo "SKIP: need root" exit "$ksft_skip" @@ -217,6 +269,16 @@ test_opts_mismatch gre icsum test_control test_old_seq gre =20 +test_tunnel_not_found +# The routing bit is the second most significant bit of the first byte +# of the GRE header, which follows the 20 byte IPv4 header. +test_corrupted_header "gre: routing bit set" GRE_INVALID_HDR \ + offset 20 u8 set 0x40 +# The GRE version sits in the low bits of the next byte. Version 1 is +# PPTP, which has no handler here. +test_corrupted_header "gre: unhandled GRE version" UNHANDLED_PROTO \ + offset 21 u8 set 0x01 + if [ -e /proc/sys/net/ipv6 ]; then test_opts_mismatch ip6gre iseq test_old_seq ip6gre --=20 2.47.3 From nobody Sat Sep 26 13:46:47 2026 Received: from mail-lf1-f41.google.com (mail-lf1-f41.google.com [209.85.167.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 288F43AE6F4 for ; Mon, 31 Aug 2026 21:52:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788213133; cv=none; b=q0B1zy2Ka9dNUq6LN5sxMpnCNGt2TYBfixlE2L81nRoWZkkStgWxG3dZRYcBMzfsVegw6gXwWGZVSNqBaaRcdh8zJ9sKUhAPEM7PE0LWxC+wVbubxazzkyWonxkUCr3OYONjOeUFGKRk1AXcYdB9wXYekXzC/zJiHykfHE1Hnss= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788213133; c=relaxed/simple; bh=lpJgQ1G09SONipa/G1j+gTjEknOSH8YBnE789jf3q3k=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hhlqVaZ3+mHvOILlS/vM6qNtaEjqv+sBnTKnXa99f7VqWpG99I4BvcdXKouDSyPKs+iD1oJW8x16e23onWIkT+Yo+4AgboEhtEVrk3aHiF71rkC8lMXjVpCuSWRUcB8QOP1YSDf/hIutinstUhz4UCDnEpZI06lc9hGeqOtTr8E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=tIq6X7k6; arc=none smtp.client-ip=209.85.167.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="tIq6X7k6" Received: by mail-lf1-f41.google.com with SMTP id 2adb3069b0e04-5b4ab4b4179so1618350e87.0 for ; Mon, 31 Aug 2026 14:52:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788213123; x=1788817923; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=+May2nMd320JoAXM5csJn+yzs/ebduDyHmgff6M1UME=; b=tIq6X7k6GL7+Q3374RVmksZbXoMIGlJ4bybiTp/E4WUlMTFkrMKD5axXD6hY3zn5zU 1lnIqi/I1KIUw+cDBubUOb1B6nNkMpzxwBWUY9fgGnJy65d523OkQr157+uVpAYWUnKl N5oMOHvde4X24EWSuIdNP/hi8ewMQ6SlQFqZKFo0+vxKomwmPqhCCICkGTJO6B0mcPpo 1SU3EhgskLvMfAp0zjrP9luOt17tLaSWayTXHSrYM3bgFx+LKnT+8U3fif/cpjhk8r7E lWS6HbCxTQkAqhWv/K5psPJOLiUCFhjw4aXaAqAkKeK5I7jHzWoxMOkRFGEo+JymrPE/ ixXw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788213123; x=1788817923; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=+May2nMd320JoAXM5csJn+yzs/ebduDyHmgff6M1UME=; b=Ie0odybup/INsH02D8pRf0d8n9tDuO/MdNIAsUOD/KJT/muaCUs1A7pDQZPgieltan C9qRWBn7LF6mAxPhvZ6mUmJenEbe8ltkehxbuXdf7ldWt5Cd3gC+rUVFqvBNEmaEK36P VDilohwCao5+NiAHRPozuVpczgCQCIKXKEw236dlUwoxSWIc4NF7sex2w9jy4czpykvf H9MzAfStlORNRVNTLIxHwhNtiHMVIYUJMsYdfv20AJ8h8NHRuxdvE82sBNpbGWqkZ9hT Z4cp1YPQR+qoLftlSFG1SwPwHDIlCrey282KFVPnAvezG+d0JCKWEoUrJYU0f7MI8aEH rwfQ== X-Forwarded-Encrypted: i=1; AKwUvBxSS5K2F5tVDiib15W6QcD9gvSGA6ilNdcezIh6E5d4jyggnr61ZRK1BBTVWG6DIBIIOS9NWEYARvozlaw=@vger.kernel.org X-Gm-Message-State: AFuF++n0JWOmMpyWRvFc5U/b9+7eg+3+m6097t7+itvGCEt558KSMtL0 Tq6px93lRJft+8NdLO19GYV5YvubA7sXqJOr7zAEknWz++EDAc7nDZLT X-Gm-Gg: AYBFou0Ku5m93HteuFvDIZJlfgPabxSToS/NSuAaHdwJP8pGQBlLf2NvIRw6fj+YNi8 xSo1VTHknWNGbJIKrHQIGh0AotLLx2xh/YsH1qbr7SHE0gzyuJwDhub4u4t6+pz/EymMwCep4oy HIn0KR6HybeIwJlXPv3QSZZ0pX5AREP7tPXMoIMwsBzx1JtK3OSueLflgcxYx5DSKMDsnzhfMJj 6RSKdwJC9p50OdU3jIEjYOVVoMs5RwvKDM779vqwPwKeg241ND/D4pRc4vu+MEMJ0jQrzsyirZK gWhrCYC5+7LHvmBc8HB6agQm5b3ooIKpxpm0+wLChvd8yK+V2L55K5wcLouOgTiqP/JSZr7rdjh /O82wliH7NTBEIcnctmEKe3uAwD8O0O3dxBz3kXsU2tY3btX0kaOCHjoA1Mqa1Cob3Q2/M6utr+ JZHa0S09bD5BhS047TY055raQgfuwfsaANkXcl/KwS8WVTdJPihSeL/cUeWCqdmjN76BZoG80Jz D2xQt10evAT8u8WceRTpLsqM2NeM6FEog== X-Received: by 2002:a05:6512:3baa:b0:5b0:197b:9827 with SMTP id 2adb3069b0e04-5b5fe058e29mr1315878e87.3.1788213122457; Mon, 31 Aug 2026 14:52:02 -0700 (PDT) Received: from dau-home-pc.. ([212.35.184.237]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b5e8a06a77sm2388782e87.48.2026.08.31.14.52.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Aug 2026 14:52:01 -0700 (PDT) From: Anton Danilov To: netdev@vger.kernel.org Cc: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , David Ahern , Simon Horman , Shuah Khan , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH net-next 08/11] ip_tunnel: add drop reasons to the transmit path Date: Tue, 1 Sep 2026 00:51:34 +0300 Message-ID: <20260831215137.549324-9-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260831215137.549324-1-littlesmilingcloud@gmail.com> References: <20260831215137.549324-1-littlesmilingcloud@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" ip_tunnel_xmit() and ip_md_tunnel_xmit() encapsulate packets that the tunnel forwards, and every failure on that path ends in the same plain kfree_skb(). The device counters separate them a little, but they are too coarse to act on: tx_errors alone covers an encapsulation failure, a routing failure, a lookup loop and a packet that is simply too big. The last one deserves attention. tnl_update_pmtu() returns -E2BIG for a packet larger than the path MTU that has the DF bit set, after it has already sent an ICMP fragmentation needed back to the sender. That is path MTU discovery working as intended, yet it lands in tx_errors next to genuine failures, so a MTU black hole cannot be told from a broken route by looking at the counters. No new reason is needed for most of it: - SKB_DROP_REASON_PKT_TOO_BIG for the case above, - SKB_DROP_REASON_IP_OUTNOROUTES when no route is found, - SKB_DROP_REASON_RECURSION_LIMIT when the route points back at the tunnel device itself, which is the "dead loop on virtual device" that reason describes, - SKB_DROP_REASON_NOMEM when the headroom cannot be expanded, - SKB_DROP_REASON_NEIGH_CREATEFAIL when the NBMA neighbour lookup fails, SKB_DROP_REASON_NO_TX_TARGET when no destination can be derived at all, and SKB_DROP_REASON_UNHANDLED_PROTO for a payload that is neither IPv4 nor IPv6, - SKB_DROP_REASON_TUNNEL_TXINFO, which already documents a packet reaching an external mode device without metadata, for the collect_md path. Only the encapsulation failure has no fitting reason, so add SKB_DROP_REASON_IP_TUNNEL_ENCAP for it. Drop reasons on transmit are not new: vxlan already reports several of them from its xmit path, and ip_tunnel_core.c reports SKB_DROP_REASON_RECURSION_LIMIT. Assisted-by: Claude-Code:claude-opus-5 Signed-off-by: Anton Danilov --- include/net/dropreason-core.h | 7 ++++++ net/ipv4/ip_tunnel.c | 41 ++++++++++++++++++++++++++++------- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/include/net/dropreason-core.h b/include/net/dropreason-core.h index d1fb52c1b0cb..2a2ac8767d68 100644 --- a/include/net/dropreason-core.h +++ b/include/net/dropreason-core.h @@ -133,6 +133,7 @@ FN(GRE_INVALID_HDR) \ FN(GRE_CSUM) \ FN(GRE_TUNNEL_NOT_FOUND) \ + FN(IP_TUNNEL_ENCAP) \ FNe(MAX) =20 /** @@ -637,6 +638,12 @@ enum skb_drop_reason { * endpoints and the key the packet carries. */ SKB_DROP_REASON_GRE_TUNNEL_NOT_FOUND, + /** + * @SKB_DROP_REASON_IP_TUNNEL_ENCAP: failed to build the + * encapsulation header of a tunnel, e.g. an unknown or + * unregistered encapsulation type. + */ + SKB_DROP_REASON_IP_TUNNEL_ENCAP, /** * @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 ab8bae8ba781..12d45f69c4d8 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -582,6 +582,7 @@ static int tnl_update_pmtu(struct net_device *dev, stru= ct sk_buff *skb, void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, u8 proto, int tunnel_hlen) { + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; struct ip_tunnel *tunnel =3D netdev_priv(dev); u32 headroom =3D sizeof(struct iphdr); struct ip_tunnel_info *tun_info; @@ -595,8 +596,10 @@ void ip_md_tunnel_xmit(struct sk_buff *skb, struct net= _device *dev, =20 tun_info =3D skb_tunnel_info(skb); if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX) || - ip_tunnel_info_af(tun_info) !=3D AF_INET)) + ip_tunnel_info_af(tun_info) !=3D AF_INET)) { + reason =3D SKB_DROP_REASON_TUNNEL_TXINFO; goto tx_error; + } key =3D &tun_info->key; memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); inner_iph =3D (const struct iphdr *)skb_inner_network_header(skb); @@ -615,8 +618,10 @@ void ip_md_tunnel_xmit(struct sk_buff *skb, struct net= _device *dev, if (!tunnel_hlen) tunnel_hlen =3D ip_encap_hlen(&tun_info->encap); =20 - if (ip_tunnel_encap(skb, &tun_info->encap, &proto, &fl4) < 0) + if (ip_tunnel_encap(skb, &tun_info->encap, &proto, &fl4) < 0) { + reason =3D SKB_DROP_REASON_IP_TUNNEL_ENCAP; goto tx_error; + } =20 use_cache =3D ip_tunnel_dst_cache_usable(skb, tun_info); if (use_cache) @@ -625,6 +630,7 @@ void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_= device *dev, rt =3D ip_route_output_key(tunnel->net, &fl4); if (IS_ERR(rt)) { DEV_STATS_INC(dev, tx_carrier_errors); + reason =3D SKB_DROP_REASON_IP_OUTNOROUTES; goto tx_error; } if (use_cache) @@ -634,6 +640,7 @@ void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_= device *dev, if (rt->dst.dev =3D=3D dev) { ip_rt_put(rt); DEV_STATS_INC(dev, collisions); + reason =3D SKB_DROP_REASON_RECURSION_LIMIT; goto tx_error; } =20 @@ -642,6 +649,7 @@ void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_= device *dev, if (tnl_update_pmtu(dev, skb, rt, df, inner_iph, tunnel_hlen, key->u.ipv4.dst, true)) { ip_rt_put(rt); + reason =3D SKB_DROP_REASON_PKT_TOO_BIG; goto tx_error; } =20 @@ -659,6 +667,7 @@ void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_= device *dev, headroom +=3D LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len; if (skb_cow_head(skb, headroom)) { ip_rt_put(rt); + reason =3D SKB_DROP_REASON_NOMEM; goto tx_dropped; } =20 @@ -673,13 +682,14 @@ void ip_md_tunnel_xmit(struct sk_buff *skb, struct ne= t_device *dev, tx_dropped: DEV_STATS_INC(dev, tx_dropped); kfree: - kfree_skb(skb); + kfree_skb_reason(skb, reason); } EXPORT_SYMBOL_GPL(ip_md_tunnel_xmit); =20 void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, const struct iphdr *tnl_params, u8 protocol) { + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; struct ip_tunnel *tunnel =3D netdev_priv(dev); struct ip_tunnel_info *tun_info =3D NULL; const struct iphdr *inner_iph; @@ -707,9 +717,15 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_de= vice *dev, =20 if (!skb_dst(skb)) { DEV_STATS_INC(dev, tx_fifo_errors); + reason =3D SKB_DROP_REASON_NO_TX_TARGET; goto tx_error; } =20 + /* Only the branches below can derive a destination. If + * none of them matches, the payload protocol is not one + * this tunnel can carry. + */ + reason =3D SKB_DROP_REASON_UNHANDLED_PROTO; tun_info =3D skb_tunnel_info(skb); if (tun_info && (tun_info->mode & IP_TUNNEL_INFO_TX) && ip_tunnel_info_af(tun_info) =3D=3D AF_INET && @@ -730,8 +746,10 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_de= vice *dev, =20 neigh =3D dst_neigh_lookup(skb_dst(skb), &ipv6_hdr(skb)->daddr); - if (!neigh) + if (!neigh) { + reason =3D SKB_DROP_REASON_NEIGH_CREATEFAIL; goto tx_error; + } =20 addr6 =3D (const struct in6_addr *)&neigh->primary_key; addr_type =3D ipv6_addr_type(addr6); @@ -748,8 +766,10 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_de= vice *dev, dst =3D addr6->s6_addr32[3]; } neigh_release(neigh); - if (do_tx_error_icmp) + if (do_tx_error_icmp) { + reason =3D SKB_DROP_REASON_NO_TX_TARGET; goto tx_error_icmp; + } } #endif else @@ -776,8 +796,10 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_de= vice *dev, tunnel->net, READ_ONCE(tunnel->parms.link), tunnel->fwmark, skb_get_hash(skb), 0); =20 - if (ip_tunnel_encap(skb, &tunnel->encap, &protocol, &fl4) < 0) + if (ip_tunnel_encap(skb, &tunnel->encap, &protocol, &fl4) < 0) { + reason =3D SKB_DROP_REASON_IP_TUNNEL_ENCAP; goto tx_error; + } =20 if (connected && md) { use_cache =3D ip_tunnel_dst_cache_usable(skb, tun_info); @@ -794,6 +816,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_dev= ice *dev, =20 if (IS_ERR(rt)) { DEV_STATS_INC(dev, tx_carrier_errors); + reason =3D SKB_DROP_REASON_IP_OUTNOROUTES; goto tx_error; } if (use_cache) @@ -807,6 +830,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_dev= ice *dev, if (rt->dst.dev =3D=3D dev) { ip_rt_put(rt); DEV_STATS_INC(dev, collisions); + reason =3D SKB_DROP_REASON_RECURSION_LIMIT; goto tx_error; } =20 @@ -816,6 +840,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_dev= ice *dev, =20 if (tnl_update_pmtu(dev, skb, rt, df, inner_iph, 0, 0, false)) { ip_rt_put(rt); + reason =3D SKB_DROP_REASON_PKT_TOO_BIG; goto tx_error; } =20 @@ -850,7 +875,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_dev= ice *dev, if (skb_cow_head(skb, max_headroom)) { ip_rt_put(rt); DEV_STATS_INC(dev, tx_dropped); - kfree_skb(skb); + kfree_skb_reason(skb, SKB_DROP_REASON_NOMEM); return; } =20 @@ -866,7 +891,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_dev= ice *dev, #endif tx_error: DEV_STATS_INC(dev, tx_errors); - kfree_skb(skb); + kfree_skb_reason(skb, reason); } EXPORT_SYMBOL_GPL(ip_tunnel_xmit); =20 --=20 2.47.3 From nobody Sat Sep 26 13:46:47 2026 Received: from mail-lj1-f175.google.com (mail-lj1-f175.google.com [209.85.208.175]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4B4743B9DAC for ; Mon, 31 Aug 2026 21:52:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788213136; cv=none; b=K8fFVUcr0HisLIIRZdBKoks6yg/u8rxhcd54tCeyFwuQLXhAhtJDZUms1g/7Cp6YtVyUKaY0w+7kT1lqIxk4mmZV0ulbsSwin0S4C9/VlNzGq4GfyMyGfIe5Y+SToTcBzwZRYDrHxenPK+kLzxnfDeyci8SH6pvOMV0hv1tWkYw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788213136; c=relaxed/simple; bh=NslG6/S+tvwfkVb7E27vf5+QTt3I9AMR0qhJKQYNKZY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CP/15Rwbu6kI2HG5++iNVw54Wu4TKcDl4K8RNKczY35v+pwpkTM+pZ6UGqzHkr9jvZOTG+BE14MhRSad4CVlQ+eMnCMaFzRUqKKVVA3T3Gjrk4xhInvWO1Mg2Jtm6GzYGWUj3x984GVSDR0G9/Q0xBaL4U0XfxnwFuzYMjh6hXo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=iJi64z0a; arc=none smtp.client-ip=209.85.208.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="iJi64z0a" Received: by mail-lj1-f175.google.com with SMTP id 38308e7fff4ca-39c953950dfso40696791fa.1 for ; Mon, 31 Aug 2026 14:52:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788213125; x=1788817925; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=+8b6bQszX04ObrSEGXy6OYQKjoQ7GM95e6LUb7G78KE=; b=iJi64z0aVIi1qZ6lz4UBaEvPoxE7aRaETg1KS+FFxJb/WHB7WQzQrWNFT+wm1xnLle 3icJK+XRrAPHvtHk0ZR1Y4glyOlYvGV/3/WLUbivusD1cIIoLSLT1ty3LrrU6GCekxJI IWhkvSenC63U5W7ttw1aflC/RH7cQDZ8O7VJ9uhTwxOVJiVLE92qEzBlIAoAI+S9B7XX KnJkjRBG8yIMtG8rsZBTk0NNVKbTZHSQthsRjKRXKQrH8V9sjhwrz+ebLSPYdXVtDjpi IgT6Fz4fWbaOHcM6buR7mJLlVCv++uro5/K0s+qpnsKuqKs1+/VHvkKXZCtJK02fRN34 6EeQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788213125; x=1788817925; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=+8b6bQszX04ObrSEGXy6OYQKjoQ7GM95e6LUb7G78KE=; b=e9wY/15u2x1Ix4hqCliQ14w1KGdc5PljWROSpFrcYeptzST53wMSHojp4sI75VEG7R afyW7N0IJH9U+kfEItm2r6IbXyfDM11jA1EjJmeF77a5tIzjXkxPPnqyoJ1KcZEfBqPN Y/pTxA1ZGeM798FU3XmN18EOrWHivhRQD2nakNrRzIxidt8ov00oanZZucTWcYA5Z+3B tWIJvJUzhAhz9CUyEmcZQa2bebTKEyY+i6b3nliycYz7sMDWlBRMFTA7uPQ5BD8y3VEJ OL0LdWAAl94Zj9DONZU8N5dssMkU6DjdbC63YHEoM+5saer+WffRZNLjtFFg+fYMC1g0 EtFg== X-Forwarded-Encrypted: i=1; AKwUvBzTbcdjTH/pySwEvJRATavd3idnWLzdl/ajHNI345zgcTUrmYwIOAHgNI/wlAGtrE3kuSUhihqhX4hSP2s=@vger.kernel.org X-Gm-Message-State: AFuF++m4FSbi4UU8x8duFMog3C7kqrBsGesQSxnH5bD2JmC/0fMUIu2W muLLR3HkV7EFhXOHvtF+y3wny2ynCMqNaIV91EjeO9iIBvSUmX0a0Mel X-Gm-Gg: AYBFou0Njpj+c0rfDp50ahj2NtqfOoxFfTP6M7hzOFNfpK34s5vf4Ev3uqGZhnHtHqe 26yzIKbzeP7td/6CgygKQRPFMpyL4Qw83cUm/LPnbg9DAcNuLCySY7rZB7shdhuO1A909VN04Sx cd94fmGUyTBVooGPEBDfWNB0/6dIMHbLhc2runPccR55jj5AP8Xeodlk2ukKaveae8TVMQ3WNxS U7rdVcgxrD3D3fbH4a6VZcQiRaIdHNP2jdJbH5npn2ZwuxfMjPFZzsUnpf/4XBsKIYONNDWrxzc bpgcx63nsQ1VVYp1b9u5DsQ9jnq+0HhMvxNTjFtcMvWAGoCRaNNgvY2yqe5RZKrv3qk3vI07Euj ZvE1U7u8BwiQTvUyj8fkcja7tx9BU3d24TouvB1uepG7mmrtiVRl2W+7vep7eTwGEHjy7SJuni8 KYdVNZc8u1C0sOt1gOftCzlYsb/3ikNSr9II/CRgxuemVODmy6oHy1iy1eF6EozqzWcANbQu4BR whogJ8ZwqYkx8UMHWylGVwRu1WVbgAqMA== X-Received: by 2002:ac2:4f03:0:b0:5b4:5846:d925 with SMTP id 2adb3069b0e04-5b5fe0bcf70mr1186559e87.21.1788213125076; Mon, 31 Aug 2026 14:52:05 -0700 (PDT) Received: from dau-home-pc.. ([212.35.184.237]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b5e8a06a77sm2388782e87.48.2026.08.31.14.52.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Aug 2026 14:52:03 -0700 (PDT) From: Anton Danilov To: netdev@vger.kernel.org Cc: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , David Ahern , Simon Horman , Shuah Khan , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH net-next 09/11] ip_gre: add drop reasons to the transmit path Date: Tue, 1 Sep 2026 00:51:35 +0300 Message-ID: <20260831215137.549324-10-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260831215137.549324-1-littlesmilingcloud@gmail.com> References: <20260831215137.549324-1-littlesmilingcloud@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The five transmit functions of ip_gre collapse about twenty distinct failures into a plain kfree_skb() and a tx_dropped increment, which says nothing beyond "the tunnel did not send it". No new reason is needed. The length helpers already compute one, so pskb_inet_may_pull_reason() and pskb_may_pull_reason() are used instead of their boolean wrappers, and the rest reuses: - SKB_DROP_REASON_NOMEM for the headroom expansions, the offload handling and the trims, - SKB_DROP_REASON_TUNNEL_TXINFO for the collect_md paths, when the metadata is missing or incomplete, - SKB_DROP_REASON_UNHANDLED_PROTO for an ERSPAN version that is not implemented, - SKB_DROP_REASON_SKB_CSUM when the checksum starts before the data the tunnel is about to send. Assisted-by: Claude-Code:claude-opus-5 Signed-off-by: Anton Danilov --- net/ipv4/ip_gre.c | 101 +++++++++++++++++++++++++++++++++------------- 1 file changed, 74 insertions(+), 27 deletions(-) diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 4d9bb6d186ae..c45e9590c94d 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -511,23 +511,30 @@ static void gre_fb_xmit(struct sk_buff *skb, struct n= et_device *dev, IP_TUNNEL_DECLARE_FLAGS(flags) =3D { }; struct ip_tunnel_info *tun_info; const struct ip_tunnel_key *key; + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; int tunnel_hlen; =20 tun_info =3D skb_tunnel_info(skb); if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX) || - ip_tunnel_info_af(tun_info) !=3D AF_INET)) + ip_tunnel_info_af(tun_info) !=3D AF_INET)) { + reason =3D SKB_DROP_REASON_TUNNEL_TXINFO; goto err_free_skb; + } =20 key =3D &tun_info->key; tunnel_hlen =3D gre_calc_hlen(key->tun_flags); =20 - if (skb_cow_head(skb, dev->needed_headroom)) + if (skb_cow_head(skb, dev->needed_headroom)) { + reason =3D SKB_DROP_REASON_NOMEM; goto err_free_skb; + } =20 /* Push Tunnel header. */ if (gre_handle_offloads(skb, test_bit(IP_TUNNEL_CSUM_BIT, - tunnel->parms.o_flags))) + tunnel->parms.o_flags))) { + reason =3D SKB_DROP_REASON_NOMEM; goto err_free_skb; + } =20 __set_bit(IP_TUNNEL_CSUM_BIT, flags); __set_bit(IP_TUNNEL_KEY_BIT, flags); @@ -544,7 +551,7 @@ static void gre_fb_xmit(struct sk_buff *skb, struct net= _device *dev, return; =20 err_free_skb: - kfree_skb(skb); + kfree_skb_reason(skb, reason); DEV_STATS_INC(dev, tx_dropped); } =20 @@ -554,6 +561,7 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct = net_device *dev) IP_TUNNEL_DECLARE_FLAGS(flags) =3D { }; struct ip_tunnel_info *tun_info; const struct ip_tunnel_key *key; + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; struct erspan_metadata *md; bool truncate =3D false; __be16 proto; @@ -563,29 +571,41 @@ static void erspan_fb_xmit(struct sk_buff *skb, struc= t net_device *dev) =20 tun_info =3D skb_tunnel_info(skb); if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX) || - ip_tunnel_info_af(tun_info) !=3D AF_INET)) + ip_tunnel_info_af(tun_info) !=3D AF_INET)) { + reason =3D SKB_DROP_REASON_TUNNEL_TXINFO; goto err_free_skb; + } =20 key =3D &tun_info->key; - if (!test_bit(IP_TUNNEL_ERSPAN_OPT_BIT, tun_info->key.tun_flags)) + if (!test_bit(IP_TUNNEL_ERSPAN_OPT_BIT, tun_info->key.tun_flags)) { + reason =3D SKB_DROP_REASON_TUNNEL_TXINFO; goto err_free_skb; - if (tun_info->options_len < sizeof(*md)) + } + if (tun_info->options_len < sizeof(*md)) { + reason =3D SKB_DROP_REASON_TUNNEL_TXINFO; goto err_free_skb; + } md =3D ip_tunnel_info_opts(tun_info); =20 /* ERSPAN has fixed 8 byte GRE header */ version =3D md->version; tunnel_hlen =3D 8 + erspan_hdr_len(version); =20 - if (skb_cow_head(skb, dev->needed_headroom)) + if (skb_cow_head(skb, dev->needed_headroom)) { + reason =3D SKB_DROP_REASON_NOMEM; goto err_free_skb; + } =20 - if (gre_handle_offloads(skb, false)) + if (gre_handle_offloads(skb, false)) { + reason =3D SKB_DROP_REASON_NOMEM; goto err_free_skb; + } =20 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 =3D SKB_DROP_REASON_NOMEM; goto err_free_skb; + } truncate =3D true; } =20 @@ -617,6 +637,7 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct = net_device *dev) truncate, true); proto =3D htons(ETH_P_ERSPAN2); } else { + reason =3D SKB_DROP_REASON_UNHANDLED_PROTO; goto err_free_skb; } =20 @@ -629,7 +650,7 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct = net_device *dev) return; =20 err_free_skb: - kfree_skb(skb); + kfree_skb_reason(skb, reason); DEV_STATS_INC(dev, tx_dropped); } =20 @@ -663,8 +684,10 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb, struct ip_tunnel *tunnel =3D netdev_priv(dev); IP_TUNNEL_DECLARE_FLAGS(flags); const struct iphdr *tnl_params; + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; =20 - if (!pskb_inet_may_pull(skb)) + reason =3D pskb_inet_may_pull_reason(skb); + if (reason) goto free_skb; =20 if (tunnel->collect_md) { @@ -675,10 +698,13 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb, if (dev->header_ops) { int pull_len =3D tunnel->hlen + sizeof(struct iphdr); =20 - if (skb_cow_head(skb, 0)) + if (skb_cow_head(skb, 0)) { + reason =3D SKB_DROP_REASON_NOMEM; goto free_skb; + } =20 - if (!pskb_may_pull(skb, pull_len)) + reason =3D pskb_may_pull_reason(skb, pull_len); + if (reason) goto free_skb; =20 tnl_params =3D (const struct iphdr *)skb->data; @@ -688,25 +714,31 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb, skb_reset_mac_header(skb); =20 if (skb->ip_summed =3D=3D CHECKSUM_PARTIAL && - skb_checksum_start(skb) < skb->data) + skb_checksum_start(skb) < skb->data) { + reason =3D SKB_DROP_REASON_SKB_CSUM; goto free_skb; + } } else { - if (skb_cow_head(skb, dev->needed_headroom)) + if (skb_cow_head(skb, dev->needed_headroom)) { + reason =3D SKB_DROP_REASON_NOMEM; goto free_skb; + } =20 tnl_params =3D &tunnel->parms.iph; } =20 ip_tunnel_flags_copy(flags, tunnel->parms.o_flags); =20 - if (gre_handle_offloads(skb, test_bit(IP_TUNNEL_CSUM_BIT, flags))) + if (gre_handle_offloads(skb, test_bit(IP_TUNNEL_CSUM_BIT, flags))) { + reason =3D SKB_DROP_REASON_NOMEM; goto free_skb; + } =20 __gre_xmit(skb, dev, tnl_params, skb->protocol, flags); return NETDEV_TX_OK; =20 free_skb: - kfree_skb(skb); + kfree_skb_reason(skb, reason); DEV_STATS_INC(dev, tx_dropped); return NETDEV_TX_OK; } @@ -716,10 +748,12 @@ static netdev_tx_t erspan_xmit(struct sk_buff *skb, { struct ip_tunnel *tunnel =3D netdev_priv(dev); IP_TUNNEL_DECLARE_FLAGS(flags); + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; bool truncate =3D false; __be16 proto; =20 - if (!pskb_inet_may_pull(skb)) + reason =3D pskb_inet_may_pull_reason(skb); + if (reason) goto free_skb; =20 if (tunnel->collect_md) { @@ -727,15 +761,21 @@ static netdev_tx_t erspan_xmit(struct sk_buff *skb, return NETDEV_TX_OK; } =20 - if (gre_handle_offloads(skb, false)) + if (gre_handle_offloads(skb, false)) { + reason =3D SKB_DROP_REASON_NOMEM; goto free_skb; + } =20 - if (skb_cow_head(skb, dev->needed_headroom)) + if (skb_cow_head(skb, dev->needed_headroom)) { + reason =3D SKB_DROP_REASON_NOMEM; goto free_skb; + } =20 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 =3D SKB_DROP_REASON_NOMEM; goto free_skb; + } truncate =3D true; } =20 @@ -756,6 +796,7 @@ static netdev_tx_t erspan_xmit(struct sk_buff *skb, truncate, true); proto =3D htons(ETH_P_ERSPAN2); } else { + reason =3D SKB_DROP_REASON_UNHANDLED_PROTO; goto free_skb; } =20 @@ -764,7 +805,7 @@ static netdev_tx_t erspan_xmit(struct sk_buff *skb, return NETDEV_TX_OK; =20 free_skb: - kfree_skb(skb); + kfree_skb_reason(skb, reason); DEV_STATS_INC(dev, tx_dropped); return NETDEV_TX_OK; } @@ -774,8 +815,10 @@ static netdev_tx_t gre_tap_xmit(struct sk_buff *skb, { struct ip_tunnel *tunnel =3D netdev_priv(dev); IP_TUNNEL_DECLARE_FLAGS(flags); + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; =20 - if (!pskb_inet_may_pull(skb)) + reason =3D pskb_inet_may_pull_reason(skb); + if (reason) goto free_skb; =20 if (tunnel->collect_md) { @@ -785,17 +828,21 @@ static netdev_tx_t gre_tap_xmit(struct sk_buff *skb, =20 ip_tunnel_flags_copy(flags, tunnel->parms.o_flags); =20 - if (gre_handle_offloads(skb, test_bit(IP_TUNNEL_CSUM_BIT, flags))) + if (gre_handle_offloads(skb, test_bit(IP_TUNNEL_CSUM_BIT, flags))) { + reason =3D SKB_DROP_REASON_NOMEM; goto free_skb; + } =20 - if (skb_cow_head(skb, dev->needed_headroom)) + if (skb_cow_head(skb, dev->needed_headroom)) { + reason =3D SKB_DROP_REASON_NOMEM; goto free_skb; + } =20 __gre_xmit(skb, dev, &tunnel->parms.iph, htons(ETH_P_TEB), flags); return NETDEV_TX_OK; =20 free_skb: - kfree_skb(skb); + kfree_skb_reason(skb, reason); DEV_STATS_INC(dev, tx_dropped); return NETDEV_TX_OK; } --=20 2.47.3 From nobody Sat Sep 26 13:46:47 2026 Received: from mail-lf1-f49.google.com (mail-lf1-f49.google.com [209.85.167.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 01E2F3BB110 for ; Mon, 31 Aug 2026 21:52:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788213137; cv=none; b=eT+w1HJc4wlpQCDIZAlS5DOu1tHH+/5yFVQADPTYmRBWftzk0CiuZD28AdVoeZRPXbZhF2cYJvDde3WatJH8ocwizhMlOtytytJepvLDnpyNSxnfH5Yq7k3k1bpQ+ijLKtWpq6zzsZqOd+9Gw15X0yIq5ElvPvBxopcTSHDjdSg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788213137; c=relaxed/simple; bh=xc6RYFjM3qum/BpEYUDxAN8AqfURwHfuXiQv33zPfyc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=sgA3QOd19vBCezNtTkVwRknJ0BDKcRQN3esEjK4t8V7PPfMHVZHFeEAye8tjHqvYrwKd/Oh/hF7fAkOzff8YPFHWBPdTHY0IWeyTDBY515h5+oWBxhujVpLaNGv74weruhX/Q87OB2IHC45W+0+ZEt1fLq0K4D2YktbvRDTA6Pc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=U7AsM77q; arc=none smtp.client-ip=209.85.167.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="U7AsM77q" Received: by mail-lf1-f49.google.com with SMTP id 2adb3069b0e04-5b4ae0b3308so114544e87.3 for ; Mon, 31 Aug 2026 14:52:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788213127; x=1788817927; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=S/AmrykVmQeKHyM0p+x7oceRSM+ptePxF2cOoh/jGjA=; b=U7AsM77qtrToIWDE4qYhw8PTLVfkliWPz/SLh7MnNEmViC0Lgotzsj/AHEery2h25L o0i9op6Wz/IQMJIs+pDdBBGhrKpSutB7xFisrPKJdgDygbll+ofUi9KSqVCRyJoh86HA obj/9Y45UUxIn+EQnbi/8FaiOq4SaSt3nNU7W5HBfo9fRUpu5ZcpJtO2mcRNtM7yP+lf +QQwIcw2ajpWsH4eDZFMy50FwdVkJPq24NGUj/+HDZNlEDwnS/Ef6mbfds1UbcizkC6p qfdopw0jYtqT5sdKSsOc/lkRe921MOHzMXIXWmio/ifPJoaIm3vdfdTo/tzzGESEICli MxQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788213127; x=1788817927; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=S/AmrykVmQeKHyM0p+x7oceRSM+ptePxF2cOoh/jGjA=; b=M1rchbL60j/PnvNWOoCto2s4n/YFXLVI0wVo7gwTSvenO5FlufjqL4thrQrtxAA211 14UYxUir5rWGEs+J/W15WuAYgfMopKpxaTfkx5NRQbloLhRK4TmtBnEeUprJ7zPMO+BT H4f9Et4V4ESWcGeBdlzyyZBaBvHEGVSoROfr3kkAklkvAaUnVNJiwvll1mum6c96aw9M yw4dmL5uqVx8ogE1hegIvZQHC8iaNvP9vsYjfwcPhsbr5UKh0rE6XfyMvQ9S2eAxExhJ x1oo4b3nmIb94Z4PX5P1LsPBYaxi0MtlyGV6ukQdW8zV52Xc4vNUDqKLlHuncmLZEh4x mHuQ== X-Forwarded-Encrypted: i=1; AKwUvBwK/YcpC6Vapogbgps6r6kyxHYYiBauId//N2/mXifnqYKDeR1PTGzoLxI2NlsSVB7rMtxlqGdNZJ3oT40=@vger.kernel.org X-Gm-Message-State: AFuF++mNYn/DbOI0DwOwV8XSKYX2ECHaRz4+XASzcNZlMb65Y+mvBkJo rtN3QJbzFIf/qHkrSFeX/8x8xizyFY+DNcdIjYAq+XGt43/UHVU19CKa X-Gm-Gg: AYBFou05hw33v77UVorJ5hrA5c7APYAa0gC0wudFQzjXz2TlSe0nOTonsH61nmxbxFG NY/AWxqpDoi4OzY/rm7r3GhDcCjdKAYMPGAZl/Cn4dqKm/lOiNSw241Y/+2gPY0FIbfCPDgykUk J416tQSYsrJXznsd+z+sRtz0FD3jSCIbI5c0RfgwAs1tWUqSdDHNaQL/BM6Ij7+YxQJIGqTYzAJ bny40tSl16eT8MFEkn9ohzxHwdyrPGyNjRN6acAcNXW2unKgUQWFXZqPYKxmle7KJSKcbPoSrRf sd5jiC5+E1L6XC0g/va6cUfpHZqPD2QUAL27OZZxMolWMlVZN/jeHJg1eHYeb6jdDJRhV1zDQHW dJfij6enuQrMhlevdFhtjMdzCYSRtZfsZBY/wGc9As1rihWg5SDeOqF96+1x06oHLLpp0L/wJrp NgMUEOX/TEL9SYkN/6u8IAFKpcCUL72jy2lqtq1uEQY0EcGb8GLaXWoA6D+Z0v3w/Ysld7FCrsB 2V6rEcqBU/lZRJMtbIXqNBzHPLUSKebJDA= X-Received: by 2002:a05:6512:3b86:b0:5b5:a8ac:6ac6 with SMTP id 2adb3069b0e04-5b5e6afc072mr8261606e87.21.1788213126478; Mon, 31 Aug 2026 14:52:06 -0700 (PDT) Received: from dau-home-pc.. ([212.35.184.237]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b5e8a06a77sm2388782e87.48.2026.08.31.14.52.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Aug 2026 14:52:05 -0700 (PDT) From: Anton Danilov To: netdev@vger.kernel.org Cc: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , David Ahern , Simon Horman , Shuah Khan , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH net-next 10/11] ip6_tunnel: add drop reasons to the transmit path Date: Tue, 1 Sep 2026 00:51:36 +0300 Message-ID: <20260831215137.549324-11-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260831215137.549324-1-littlesmilingcloud@gmail.com> References: <20260831215137.549324-1-littlesmilingcloud@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Do for the IPv6 tunnels what the previous patches did for the IPv4 ones. The situation is the same, with one difference: ip6_tnl_xmit() does not free the packet itself, it returns an error and the callers do, so the reason has to travel with it. Give it an output parameter, and pass it down through ipxip6_tnl_xmit(), __gre6_xmit() and the three ip6gre_xmit_*() helpers to the two places that actually drop. ip6_gre is converted in the same patch because it calls ip6_tnl_xmit() and would not build otherwise. The reasons are the ones already used on the IPv4 side: SKB_DROP_REASON_PKT_TOO_BIG for a packet that exceeds the path MTU, SKB_DROP_REASON_IP_OUTNOROUTES for the route lookups, SKB_DROP_REASON_RECURSION_LIMIT for a route pointing back at the tunnel, SKB_DROP_REASON_NOMEM for the allocations, SKB_DROP_REASON_TUNNEL_TXINFO for the collect_md metadata checks and SKB_DROP_REASON_NEIGH_CREATEFAIL for the neighbour lookup. Two more fit here: SKB_DROP_REASON_DEV_READY when ip6_tnl_xmit_ctl() refuses the transmit, and SKB_DROP_REASON_IPV6_BAD_EXTHDR when the tunnel encapsulation limit option leaves no room for another header. Assisted-by: Claude-Code:claude-opus-5 Signed-off-by: Anton Danilov --- include/net/ip6_tunnel.h | 3 +- net/ipv6/ip6_gre.c | 121 ++++++++++++++++++++++++++++----------- net/ipv6/ip6_tunnel.c | 72 +++++++++++++++++------ 3 files changed, 141 insertions(+), 55 deletions(-) diff --git a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h index b99805ee2fd1..95f6d12254df 100644 --- a/include/net/ip6_tunnel.h +++ b/include/net/ip6_tunnel.h @@ -143,7 +143,8 @@ int ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff = *skb, int ip6_tnl_xmit_ctl(struct ip6_tnl *t, const struct in6_addr *laddr, const struct in6_addr *raddr); int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, - struct flowi6 *fl6, int encap_limit, __u32 *pmtu, __u8 proto); + struct flowi6 *fl6, int encap_limit, __u32 *pmtu, __u8 proto, + enum skb_drop_reason *reason); __u16 ip6_tnl_parse_tlv_enc_lim(struct sk_buff *skb, __u8 *raw); __u32 ip6_tnl_get_cap(struct ip6_tnl *t, const struct in6_addr *laddr, const struct in6_addr *raddr); diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 27fbe175beec..42a033640716 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -734,7 +734,8 @@ static struct ip_tunnel_info *skb_tunnel_info_txcheck(s= truct sk_buff *skb) static netdev_tx_t __gre6_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, struct flowi6 *fl6, int encap_limit, - __u32 *pmtu, __be16 proto) + __u32 *pmtu, __be16 proto, + enum skb_drop_reason *reason) { struct ip6_tnl *tunnel =3D netdev_priv(dev); IP_TUNNEL_DECLARE_FLAGS(flags); @@ -758,8 +759,10 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb, =20 tun_info =3D skb_tunnel_info_txcheck(skb); if (IS_ERR(tun_info) || - unlikely(ip_tunnel_info_af(tun_info) !=3D AF_INET6)) + unlikely(ip_tunnel_info_af(tun_info) !=3D AF_INET6)) { + *reason =3D SKB_DROP_REASON_TUNNEL_TXINFO; return -EINVAL; + } =20 key =3D &tun_info->key; memset(fl6, 0, sizeof(*fl6)); @@ -777,8 +780,11 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb, ip_tunnel_flags_and(flags, flags, key->tun_flags); tun_hlen =3D gre_calc_hlen(flags); =20 - if (skb_cow_head(skb, dev->needed_headroom ?: tun_hlen + tunnel->encap_h= len)) + if (skb_cow_head(skb, dev->needed_headroom ?: + tun_hlen + tunnel->encap_hlen)) { + *reason =3D SKB_DROP_REASON_NOMEM; return -ENOMEM; + } =20 gre_build_header(skb, tun_hlen, flags, protocol, @@ -788,8 +794,10 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb, 0); =20 } else { - if (skb_cow_head(skb, dev->needed_headroom ?: tunnel->hlen)) + if (skb_cow_head(skb, dev->needed_headroom ?: tunnel->hlen)) { + *reason =3D SKB_DROP_REASON_NOMEM; return -ENOMEM; + } =20 ip_tunnel_flags_copy(flags, tunnel->parms.o_flags); =20 @@ -801,10 +809,11 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb, } =20 return ip6_tnl_xmit(skb, dev, dsfield, fl6, encap_limit, pmtu, - NEXTHDR_GRE); + NEXTHDR_GRE, reason); } =20 -static inline int ip6gre_xmit_ipv4(struct sk_buff *skb, struct net_device = *dev) +static inline int ip6gre_xmit_ipv4(struct sk_buff *skb, struct net_device = *dev, + enum skb_drop_reason *reason) { struct ip6_tnl *t =3D netdev_priv(dev); int encap_limit =3D -1; @@ -821,11 +830,13 @@ static inline int ip6gre_xmit_ipv4(struct sk_buff *sk= b, struct net_device *dev) =20 err =3D gre_handle_offloads(skb, test_bit(IP_TUNNEL_CSUM_BIT, t->parms.o_flags)); - if (err) + if (err) { + *reason =3D SKB_DROP_REASON_NOMEM; return -1; + } =20 err =3D __gre6_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu, - skb->protocol); + skb->protocol, reason); if (err !=3D 0) { /* XXX: send ICMP error even if DF is not set. */ if (err =3D=3D -EMSGSIZE) @@ -837,7 +848,8 @@ static inline int ip6gre_xmit_ipv4(struct sk_buff *skb,= struct net_device *dev) return 0; } =20 -static inline int ip6gre_xmit_ipv6(struct sk_buff *skb, struct net_device = *dev) +static inline int ip6gre_xmit_ipv6(struct sk_buff *skb, struct net_device = *dev, + enum skb_drop_reason *reason) { struct ip6_tnl *t =3D netdev_priv(dev); struct ipv6hdr *ipv6h =3D ipv6_hdr(skb); @@ -847,19 +859,25 @@ static inline int ip6gre_xmit_ipv6(struct sk_buff *sk= b, struct net_device *dev) __u32 mtu; int err; =20 - if (ipv6_addr_equal(&t->parms.raddr, &ipv6h->saddr)) + if (ipv6_addr_equal(&t->parms.raddr, &ipv6h->saddr)) { + *reason =3D SKB_DROP_REASON_RECURSION_LIMIT; return -1; + } =20 if (!t->parms.collect_md && - prepare_ip6gre_xmit_ipv6(skb, dev, &fl6, &dsfield, &encap_limit)) + prepare_ip6gre_xmit_ipv6(skb, dev, &fl6, &dsfield, &encap_limit)) { + *reason =3D SKB_DROP_REASON_IPV6_BAD_EXTHDR; return -1; + } =20 if (gre_handle_offloads(skb, test_bit(IP_TUNNEL_CSUM_BIT, - t->parms.o_flags))) + t->parms.o_flags))) { + *reason =3D SKB_DROP_REASON_NOMEM; return -1; + } =20 err =3D __gre6_xmit(skb, dev, dsfield, &fl6, encap_limit, - &mtu, skb->protocol); + &mtu, skb->protocol, reason); if (err !=3D 0) { if (err =3D=3D -EMSGSIZE) icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); @@ -869,7 +887,8 @@ static inline int ip6gre_xmit_ipv6(struct sk_buff *skb,= struct net_device *dev) return 0; } =20 -static int ip6gre_xmit_other(struct sk_buff *skb, struct net_device *dev) +static int ip6gre_xmit_other(struct sk_buff *skb, struct net_device *dev, + enum skb_drop_reason *reason) { struct ip6_tnl *t =3D netdev_priv(dev); int encap_limit =3D -1; @@ -879,14 +898,19 @@ static int ip6gre_xmit_other(struct sk_buff *skb, str= uct net_device *dev) int err; =20 if (!t->parms.collect_md && - prepare_ip6gre_xmit_other(skb, dev, &fl6, &dsfield, &encap_limit)) + prepare_ip6gre_xmit_other(skb, dev, &fl6, &dsfield, &encap_limit)) { + *reason =3D SKB_DROP_REASON_IPV6_BAD_EXTHDR; return -1; + } =20 err =3D gre_handle_offloads(skb, test_bit(IP_TUNNEL_CSUM_BIT, t->parms.o_flags)); - if (err) + if (err) { + *reason =3D SKB_DROP_REASON_NOMEM; return err; - err =3D __gre6_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu, skb->prot= ocol); + } + err =3D __gre6_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu, + skb->protocol, reason); =20 return err; } @@ -894,26 +918,30 @@ static int ip6gre_xmit_other(struct sk_buff *skb, str= uct net_device *dev) static netdev_tx_t ip6gre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) { + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; struct ip6_tnl *t =3D netdev_priv(dev); __be16 payload_protocol; int ret; =20 - if (!pskb_inet_may_pull(skb)) + reason =3D pskb_inet_may_pull_reason(skb); + if (reason) goto tx_err; =20 - if (!ip6_tnl_xmit_ctl(t, &t->parms.laddr, &t->parms.raddr)) + if (!ip6_tnl_xmit_ctl(t, &t->parms.laddr, &t->parms.raddr)) { + reason =3D SKB_DROP_REASON_DEV_READY; goto tx_err; + } =20 payload_protocol =3D skb_protocol(skb, true); switch (payload_protocol) { case htons(ETH_P_IP): - ret =3D ip6gre_xmit_ipv4(skb, dev); + ret =3D ip6gre_xmit_ipv4(skb, dev, &reason); break; case htons(ETH_P_IPV6): - ret =3D ip6gre_xmit_ipv6(skb, dev); + ret =3D ip6gre_xmit_ipv6(skb, dev, &reason); break; default: - ret =3D ip6gre_xmit_other(skb, dev); + ret =3D ip6gre_xmit_other(skb, dev, &reason); break; } =20 @@ -926,7 +954,7 @@ static netdev_tx_t ip6gre_tunnel_xmit(struct sk_buff *s= kb, if (!t->parms.collect_md || !IS_ERR(skb_tunnel_info_txcheck(skb))) DEV_STATS_INC(dev, tx_errors); DEV_STATS_INC(dev, tx_dropped); - kfree_skb(skb); + kfree_skb_reason(skb, reason); return NETDEV_TX_OK; } =20 @@ -937,6 +965,7 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff= *skb, struct ip6_tnl *t =3D netdev_priv(dev); struct dst_entry *dst =3D skb_dst(skb); IP_TUNNEL_DECLARE_FLAGS(flags) =3D { }; + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; bool truncate =3D false; int encap_limit =3D -1; __u8 dsfield =3D false; @@ -946,18 +975,25 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_bu= ff *skb, __u32 mtu; int nhoff; =20 - if (!pskb_inet_may_pull(skb)) + reason =3D pskb_inet_may_pull_reason(skb); + if (reason) goto tx_err; =20 - if (!ip6_tnl_xmit_ctl(t, &t->parms.laddr, &t->parms.raddr)) + if (!ip6_tnl_xmit_ctl(t, &t->parms.laddr, &t->parms.raddr)) { + reason =3D SKB_DROP_REASON_DEV_READY; goto tx_err; + } =20 - if (gre_handle_offloads(skb, false)) + if (gre_handle_offloads(skb, false)) { + reason =3D SKB_DROP_REASON_NOMEM; goto tx_err; + } =20 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 =3D SKB_DROP_REASON_NOMEM; goto tx_err; + } truncate =3D true; } =20 @@ -977,8 +1013,10 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_bu= ff *skb, truncate =3D true; } =20 - if (skb_cow_head(skb, dev->needed_headroom ?: t->hlen)) + if (skb_cow_head(skb, dev->needed_headroom ?: t->hlen)) { + reason =3D SKB_DROP_REASON_NOMEM; goto tx_err; + } =20 IPCB(skb)->flags =3D 0; =20 @@ -992,8 +1030,10 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_bu= ff *skb, =20 tun_info =3D skb_tunnel_info_txcheck(skb); if (IS_ERR(tun_info) || - unlikely(ip_tunnel_info_af(tun_info) !=3D AF_INET6)) + unlikely(ip_tunnel_info_af(tun_info) !=3D AF_INET6)) { + reason =3D SKB_DROP_REASON_TUNNEL_TXINFO; goto tx_err; + } =20 key =3D &tun_info->key; memset(&fl6, 0, sizeof(fl6)); @@ -1005,10 +1045,14 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_= buff *skb, =20 dsfield =3D key->tos; if (!test_bit(IP_TUNNEL_ERSPAN_OPT_BIT, - tun_info->key.tun_flags)) + tun_info->key.tun_flags)) { + reason =3D SKB_DROP_REASON_TUNNEL_TXINFO; goto tx_err; - if (tun_info->options_len < sizeof(*md)) + } + if (tun_info->options_len < sizeof(*md)) { + reason =3D SKB_DROP_REASON_TUNNEL_TXINFO; goto tx_err; + } md =3D ip_tunnel_info_opts(tun_info); =20 tun_id =3D tunnel_id_to_key32(key->tun_id); @@ -1026,6 +1070,7 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_bu= ff *skb, truncate, false); proto =3D htons(ETH_P_ERSPAN2); } else { + reason =3D SKB_DROP_REASON_UNHANDLED_PROTO; goto tx_err; } } else { @@ -1036,11 +1081,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 =3D SKB_DROP_REASON_RECURSION_LIMIT; goto tx_err; + } if (prepare_ip6gre_xmit_ipv6(skb, dev, &fl6, - &dsfield, &encap_limit)) + &dsfield, &encap_limit)) { + reason =3D SKB_DROP_REASON_IPV6_BAD_EXTHDR; goto tx_err; + } break; default: memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6)); @@ -1059,6 +1109,7 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_bu= ff *skb, truncate, false); proto =3D htons(ETH_P_ERSPAN2); } else { + reason =3D SKB_DROP_REASON_UNHANDLED_PROTO; goto tx_err; } =20 @@ -1077,7 +1128,7 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_bu= ff *skb, dst->ops->update_pmtu(dst, NULL, skb, mtu, false); } err =3D ip6_tnl_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu, - NEXTHDR_GRE); + NEXTHDR_GRE, &reason); if (err !=3D 0) { /* XXX: send ICMP error even if DF is not set. */ if (err =3D=3D -EMSGSIZE) { @@ -1096,7 +1147,7 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_bu= ff *skb, 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; } =20 diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 85578fa125bc..ab45601b2a68 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -1110,7 +1110,7 @@ EXPORT_SYMBOL_GPL(ip6_tnl_xmit_ctl); =20 int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, struct flowi6 *fl6, int encap_limit, __u32 *pmtu, - __u8 proto) + __u8 proto, enum skb_drop_reason *reason) { struct ip6_tnl *t =3D netdev_priv(dev); struct net *net =3D t->net; @@ -1143,13 +1143,17 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_de= vice *dev, __u8 dsfield, struct neighbour *neigh; int addr_type; =20 - if (!skb_dst(skb)) + if (!skb_dst(skb)) { + *reason =3D SKB_DROP_REASON_NO_TX_TARGET; goto tx_err_link_failure; + } =20 neigh =3D dst_neigh_lookup(skb_dst(skb), &ipv6_hdr(skb)->daddr); - if (!neigh) + if (!neigh) { + *reason =3D SKB_DROP_REASON_NEIGH_CREATEFAIL; goto tx_err_link_failure; + } =20 addr6 =3D (struct in6_addr *)&neigh->primary_key; addr_type =3D ipv6_addr_type(addr6); @@ -1162,8 +1166,10 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_dev= ice *dev, __u8 dsfield, } else if (payload_protocol =3D=3D htons(ETH_P_IP)) { const struct rtable *rt =3D skb_rtable(skb); =20 - if (!rt) + if (!rt) { + *reason =3D SKB_DROP_REASON_IP_OUTNOROUTES; goto tx_err_link_failure; + } =20 if (rt->rt_gw_family =3D=3D AF_INET6) memcpy(&fl6->daddr, &rt->rt_gw6, sizeof(fl6->daddr)); @@ -1180,8 +1186,10 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_dev= ice *dev, __u8 dsfield, if (use_cache) dst =3D dst_cache_get(&t->dst_cache); =20 - if (!ip6_tnl_xmit_ctl(t, &fl6->saddr, &fl6->daddr)) + if (!ip6_tnl_xmit_ctl(t, &fl6->saddr, &fl6->daddr)) { + *reason =3D SKB_DROP_REASON_DEV_READY; goto tx_err_link_failure; + } =20 if (!dst) { route_lookup: @@ -1190,18 +1198,23 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_de= vice *dev, __u8 dsfield, =20 dst =3D ip6_route_output(net, NULL, fl6); =20 - if (dst->error) + if (dst->error) { + *reason =3D SKB_DROP_REASON_IP_OUTNOROUTES; goto tx_err_link_failure; + } dst =3D xfrm_lookup(net, dst, flowi6_to_flowi(fl6), NULL, 0); if (IS_ERR(dst)) { err =3D PTR_ERR(dst); dst =3D NULL; + *reason =3D SKB_DROP_REASON_IP_OUTNOROUTES; goto tx_err_link_failure; } if (t->parms.collect_md && ipv6_addr_any(&fl6->saddr) && ipv6_dev_get_saddr(net, ip6_dst_idev(dst)->dev, - &fl6->daddr, 0, &fl6->saddr)) + &fl6->daddr, 0, &fl6->saddr)) { + *reason =3D SKB_DROP_REASON_NO_TX_TARGET; goto tx_err_link_failure; + } ndst =3D dst; } =20 @@ -1211,6 +1224,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_devi= ce *dev, __u8 dsfield, DEV_STATS_INC(dev, collisions); net_warn_ratelimited("%s: Local routing loop detected!\n", t->parms.name); + *reason =3D SKB_DROP_REASON_RECURSION_LIMIT; goto tx_err_dst_release; } mtu =3D dst6_mtu(dst) - eth_hlen - psh_hlen - t->tun_hlen; @@ -1225,6 +1239,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_devi= ce *dev, __u8 dsfield, if (skb->len - t->tun_hlen - eth_hlen > mtu && !skb_is_gso(skb)) { *pmtu =3D mtu; err =3D -EMSGSIZE; + *reason =3D SKB_DROP_REASON_PKT_TOO_BIG; goto tx_err_dst_release; } =20 @@ -1247,12 +1262,16 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_de= vice *dev, __u8 dsfield, */ max_headroom +=3D LL_RESERVED_SPACE(tdev); =20 - if (skb_cow_head(skb, max_headroom)) + if (skb_cow_head(skb, max_headroom)) { + *reason =3D SKB_DROP_REASON_NOMEM; goto tx_err_dst_release; + } =20 if (t->parms.collect_md) { - if (t->encap.type !=3D TUNNEL_ENCAP_NONE) + if (t->encap.type !=3D TUNNEL_ENCAP_NONE) { + *reason =3D SKB_DROP_REASON_IP_TUNNEL_ENCAP; goto tx_err_dst_release; + } } else { if (use_cache && ndst) dst_cache_set_ip6(&t->dst_cache, ndst, &fl6->saddr); @@ -1276,8 +1295,10 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_dev= ice *dev, __u8 dsfield, ip_tunnel_adj_headroom(dev, max_headroom); =20 err =3D ip6_tnl_encap(skb, t, &proto, fl6); - if (err) + if (err) { + *reason =3D SKB_DROP_REASON_IP_TUNNEL_ENCAP; return err; + } =20 if (encap_limit >=3D 0) { init_tel_txopt(&opt, encap_limit); @@ -1306,7 +1327,7 @@ EXPORT_SYMBOL(ip6_tnl_xmit); =20 static inline int ipxip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, - u8 protocol) + u8 protocol, enum skb_drop_reason *reason) { struct ip6_tnl *t =3D netdev_priv(dev); struct ipv6hdr *ipv6h; @@ -1320,8 +1341,10 @@ ipxip6_tnl_xmit(struct sk_buff *skb, struct net_devi= ce *dev, int err; =20 tproto =3D READ_ONCE(t->parms.proto); - if (tproto !=3D protocol && tproto !=3D 0) + if (tproto !=3D protocol && tproto !=3D 0) { + *reason =3D SKB_DROP_REASON_UNHANDLED_PROTO; return -1; + } =20 if (t->parms.collect_md) { struct ip_tunnel_info *tun_info; @@ -1329,8 +1352,10 @@ ipxip6_tnl_xmit(struct sk_buff *skb, struct net_devi= ce *dev, =20 tun_info =3D skb_tunnel_info(skb); if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX) || - ip_tunnel_info_af(tun_info) !=3D AF_INET6)) + ip_tunnel_info_af(tun_info) !=3D AF_INET6)) { + *reason =3D SKB_DROP_REASON_TUNNEL_TXINFO; return -1; + } key =3D &tun_info->key; memset(&fl6, 0, sizeof(fl6)); fl6.flowi6_proto =3D protocol; @@ -1367,6 +1392,7 @@ ipxip6_tnl_xmit(struct sk_buff *skb, struct net_devic= e *dev, if (tel->encap_limit =3D=3D 0) { icmpv6_ndo_send(skb, ICMPV6_PARAMPROB, ICMPV6_HDR_FIELD, offset + 2); + *reason =3D SKB_DROP_REASON_IPV6_BAD_EXTHDR; return -1; } encap_limit =3D tel->encap_limit - 1; @@ -1408,13 +1434,15 @@ ipxip6_tnl_xmit(struct sk_buff *skb, struct net_dev= ice *dev, fl6.flowi6_uid =3D sock_net_uid(dev_net(dev), NULL); dsfield =3D INET_ECN_encapsulate(dsfield, orig_dsfield); =20 - if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6)) + if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6)) { + *reason =3D SKB_DROP_REASON_NOMEM; return -1; + } =20 skb_set_inner_ipproto(skb, protocol); =20 err =3D ip6_tnl_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu, - protocol); + protocol, reason); if (err !=3D 0) { /* XXX: send ICMP error even if DF is not set. */ if (err =3D=3D -EMSGSIZE) @@ -1429,6 +1457,7 @@ ipxip6_tnl_xmit(struct sk_buff *skb, struct net_devic= e *dev, default: break; } + *reason =3D SKB_DROP_REASON_PKT_TOO_BIG; return -1; } =20 @@ -1438,11 +1467,13 @@ ipxip6_tnl_xmit(struct sk_buff *skb, struct net_dev= ice *dev, static netdev_tx_t ip6_tnl_start_xmit(struct sk_buff *skb, struct net_device *dev) { + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; struct ip6_tnl *t =3D netdev_priv(dev); u8 ipproto; int ret; =20 - if (!pskb_inet_may_pull(skb)) + reason =3D pskb_inet_may_pull_reason(skb); + if (reason) goto tx_err; =20 switch (skb->protocol) { @@ -1450,18 +1481,21 @@ ip6_tnl_start_xmit(struct sk_buff *skb, struct net_= device *dev) ipproto =3D IPPROTO_IPIP; break; case htons(ETH_P_IPV6): - if (ip6_tnl_addr_conflict(t, ipv6_hdr(skb))) + if (ip6_tnl_addr_conflict(t, ipv6_hdr(skb))) { + reason =3D SKB_DROP_REASON_RECURSION_LIMIT; goto tx_err; + } ipproto =3D IPPROTO_IPV6; break; case htons(ETH_P_MPLS_UC): ipproto =3D IPPROTO_MPLS; break; default: + reason =3D SKB_DROP_REASON_UNHANDLED_PROTO; goto tx_err; } =20 - ret =3D ipxip6_tnl_xmit(skb, dev, ipproto); + ret =3D ipxip6_tnl_xmit(skb, dev, ipproto, &reason); if (ret < 0) goto tx_err; =20 @@ -1470,7 +1504,7 @@ ip6_tnl_start_xmit(struct sk_buff *skb, struct net_de= vice *dev) tx_err: DEV_STATS_INC(dev, tx_errors); DEV_STATS_INC(dev, tx_dropped); - kfree_skb(skb); + kfree_skb_reason(skb, reason); return NETDEV_TX_OK; } =20 --=20 2.47.3 From nobody Sat Sep 26 13:46:47 2026 Received: from mail-lf1-f43.google.com (mail-lf1-f43.google.com [209.85.167.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E66C43BCD05 for ; Mon, 31 Aug 2026 21:52:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788213136; cv=none; b=kDSGiSECzSc1nU+IwMQdCIxwh5BrCfMk8DIGhzIYJV/KijnGeKoOezVB/ROAd+pTq5rwis9fFvMF1HP/PpvnIOm/4y7lXF9Ldo8dDKwfjWnAqEkT4VaD+VovIkpGhHsgoumd1uvUTADQoTwAzC+t5qRmUcFqBjGO4/edjL7Bjmc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788213136; c=relaxed/simple; bh=DKx6E5dImMHY5Yp7PtZ+11Xgio+IIf1+fa0J4Yfua5w=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FUf0+sYu+7QVHhoZ4k75lngKaNcqTcUrJwTXM/GBzIWNPHgCxBehcHM/lVNUHt1EGOWLLtbgF9XZs1t5GFY/DLbclil/JpakLZwcDTyh6PNTWEPeqOoUeq6GzHUp0gtYLDMu7zuj4J+t/OF0aQgPtg8oaxaoNFvPP7+PIKmodP4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=FVgo4FjY; arc=none smtp.client-ip=209.85.167.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="FVgo4FjY" Received: by mail-lf1-f43.google.com with SMTP id 2adb3069b0e04-5b5e18f0439so3333366e87.2 for ; Mon, 31 Aug 2026 14:52:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788213128; x=1788817928; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=zSBImvVt2nvI5IA5hzH0bnJG/0pKCpXdDgr7PN684mk=; b=FVgo4FjYMnrXsqLzBYzYwyqThIHtsqfWwPPL+TflXy8XWHAiS6fkyp9DX5EwI+wQYW WCF5znIy0U4U+mJbuwLikyVCQyIXkDYZFxGBxM1Jzj8crjpN6J6dW5CLCX0RJDGmgcKT 3HoF/9pr/eMg65bpE5PVEGsvaO4povUSeyuCgFpOQ5Hqt+qctuPp1o2qLEi7ZvGT9ghE CBt4dV3Y34RkOQ0bDcn+ssnlkiPgJz7uykTWPhRQh/f92bcskU0VDJxZE0beA3N321p3 rBADMULBVB22RZv/mqvRdYEbeVJt+ifkXNXlda31YSRPiTHpeah/+eYjcCNymRov2d+a pWMg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788213128; x=1788817928; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=zSBImvVt2nvI5IA5hzH0bnJG/0pKCpXdDgr7PN684mk=; b=h0uPIffPWs5FZc1u1AtAvtuwZlLWmvA8LZLOXyvs0HtpiMWCOA0fxUZpNqK5CEUjhj +cyUvvWwn9OcevZebNUyZQh1nhW1ntDNbFPytxhdhYQB/PZHnJJILf0UVlyMBW9Fkth7 K81tJ5rvQTPvucVYZa/CJxnN/q/99uPxxc2T6BI35wXDZiQM/Rxy3vLRr/WaqonoF6TR VjgRX9rsqIuxWuQ6/o883Ca3FSCv+vGKduYdfUq8P05b8nX5TsU8ETdYk28wcn2aOH2w YySQfB9A4qraYue54/o/lzpR3qyOO3HFbInfuwS/RckERVUq27LIAIwJRYMdswQHnyqB QLAw== X-Forwarded-Encrypted: i=1; AKwUvBzqcQzwUgb6toIQ4G45Qg+VS64+L9FA26HqTDUjM4DwY1LjWb7TCCVJCLTnQkWjTUuYqePG/zddYXfC2e0=@vger.kernel.org X-Gm-Message-State: AFuF++m1wiALsKB6vSS4G5Zx2vKau+Eb9n2RKzdAzfwSTx6PIrpbmMn2 4uB+pv0RqHNMwNa3fo2ZaZpXGtC6uAS1KsCxo6T8ORTgmVmHlOdDbWys X-Gm-Gg: AYBFou1exgqQpuPOhnt1sADQqwcouMcHCVVQEZLdz5QqDDn97UDakiiIczM/ssDDsg2 HvIxJgT+FesYH8QIPk4oq47ZeTC3R7oKBmes2hRhGT/z9kTPd5o9zvR8csBtHrdc8dFXp5qHczU xjBhkkR+eJ+FIKnChaj95W7tb5nxee7xRye7LFqKuHRrVRbSGByrbmg5fGkm5UqVpbaDBz6ckGG 6VyVPam7rTXinRuHLxliYQkwD+r3/kF+wPNlwc9gZPr3PfEN8ZR43VY+CXEdJ3T0Tf1i9j/V5gD KTfdhjztmiFhHjG2NiKcsg4zDFmz8qqAvEj1oGjSz0nryTr0EKvdtZMH74ffL5KBNHs1zd05hgu X/wENX4l23yYBEBgzgAwnC48s6AOM2fPTrtK5aYHyF4zhs2Hs+moElaepE7412RarO/xz3gJTxr r+KkARZJluO4tP1m+QK4ABtWKmJEtMtRMxJm6/HMo3b6UreUul6lnXTsNJF6UYMQtCetHwzigsF zGqUp6m1CRr5Y1vk2+Grlp16sACek6+tQ== X-Received: by 2002:a05:6512:4014:b0:5b4:a836:13fd with SMTP id 2adb3069b0e04-5b5fe0fbbaamr1575023e87.22.1788213127704; Mon, 31 Aug 2026 14:52:07 -0700 (PDT) Received: from dau-home-pc.. ([212.35.184.237]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b5e8a06a77sm2388782e87.48.2026.08.31.14.52.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Aug 2026 14:52:07 -0700 (PDT) From: Anton Danilov To: netdev@vger.kernel.org Cc: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , David Ahern , Simon Horman , Shuah Khan , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH net-next 11/11] selftests: net: cover the tunnel transmit drop reasons Date: Tue, 1 Sep 2026 00:51:37 +0300 Message-ID: <20260831215137.549324-12-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260831215137.549324-1-littlesmilingcloud@gmail.com> References: <20260831215137.549324-1-littlesmilingcloud@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Extend the tunnel drop reason test with three failures of the transmit path, all on GRE: - an underlay that cannot carry what the tunnel advertises, so the encapsulated packet does not fit the path MTU and is dropped after an ICMP fragmentation needed is sent back. This is the case worth telling apart from the others: path MTU discovery is working as intended, and until now the drop was indistinguishable from a real failure, - a device in external mode receiving traffic that carries no tunnel metadata, reported as TUNNEL_TXINFO, - a tunnel whose remote endpoint has no route, reported as IP_OUTNOROUTES. Assisted-by: Claude-Code:claude-opus-5 Signed-off-by: Anton Danilov --- .../selftests/net/tunnel_drop_reasons.sh | 58 ++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/net/tunnel_drop_reasons.sh b/tools/tes= ting/selftests/net/tunnel_drop_reasons.sh index aad003f0efe5..5639e29365a4 100755 --- a/tools/testing/selftests/net/tunnel_drop_reasons.sh +++ b/tools/testing/selftests/net/tunnel_drop_reasons.sh @@ -26,6 +26,11 @@ # GRE_TUNNEL_NOT_FOUND. It is triggered here by giving the two # endpoints different keys. # +# On the transmit side, the reasons reported while encapsulating are +# checked too: a packet that does not fit the path MTU, a device in +# external mode that receives no metadata, and a tunnel whose remote +# endpoint has no route. +# # - a header with the routing bit set is reported as GRE_INVALID_HDR, # and a header announcing a GRE version nobody handles is reported as # UNHANDLED_PROTO. Both are triggered by corrupting the GRE header @@ -81,6 +86,7 @@ setup_tracing() =20 setup_ns_pair() { + PING_ARGS=3D"" cleanup_all_ns setup_ns NS_SND NS_RCV =20 @@ -122,9 +128,15 @@ addr_tunnels() ip -n "$NS_RCV" addr add "$TUN_RCV/24" dev gre_test } =20 +# Traffic used by check_reason(). Tests that need something else set +# PING_ARGS before calling it. +PING_ARGS=3D"" + send_traffic() { - ip netns exec "$NS_SND" ping -c 2 -W 1 "$TUN_RCV" >/dev/null 2>&1 + # shellcheck disable=3DSC2086 + ip netns exec "$NS_SND" ping -c 2 -W 1 $PING_ARGS "$TUN_RCV" \ + >/dev/null 2>&1 # Let the tracepoint records reach the trace buffer. sleep 1 } @@ -254,6 +266,46 @@ test_corrupted_header() check_reason "$name" "$want" } =20 +test_tx_pkt_too_big() +{ + setup_ns_pair + # The underlay cannot carry what the tunnel advertises, so the + # encapsulated packet does not fit the path MTU. The kernel sends + # an ICMP fragmentation needed back and drops it, which is path MTU + # discovery working as intended. + ip -n "$NS_SND" link set veth_s mtu 1280 + ip -n "$NS_RCV" link set veth_r mtu 1280 + add_gre "$NS_SND" "$SND_V4" "$RCV_V4" + add_gre "$NS_RCV" "$RCV_V4" "$SND_V4" + ip -n "$NS_SND" link set gre_test mtu 1500 + addr_tunnels + + PING_ARGS=3D"-s 1400 -M do" + check_reason "gre: packet does not fit the path MTU" PKT_TOO_BIG +} + +test_tx_no_metadata() +{ + setup_ns_pair + # A device in external mode expects the destination to come from + # the tunnel metadata, which plain traffic does not carry. + ip -n "$NS_SND" link add gre_test type gre external + ip -n "$NS_SND" link set gre_test up + ip -n "$NS_SND" addr add "$TUN_SND/24" dev gre_test + + check_reason "gre: external mode without metadata" TUNNEL_TXINFO +} + +test_tx_no_route() +{ + setup_ns_pair + # Nothing knows how to reach the remote endpoint of the tunnel. + add_gre "$NS_SND" "$SND_V4" 172.31.255.254 + ip -n "$NS_SND" addr add "$TUN_SND/24" dev gre_test + + check_reason "gre: no route to the remote endpoint" IP_OUTNOROUTES +} + if [ "$(id -u)" -ne 0 ]; then echo "SKIP: need root" exit "$ksft_skip" @@ -279,6 +331,10 @@ test_corrupted_header "gre: routing bit set" GRE_INVAL= ID_HDR \ test_corrupted_header "gre: unhandled GRE version" UNHANDLED_PROTO \ offset 21 u8 set 0x01 =20 +test_tx_pkt_too_big +test_tx_no_metadata +test_tx_no_route + if [ -e /proc/sys/net/ipv6 ]; then test_opts_mismatch ip6gre iseq test_old_seq ip6gre --=20 2.47.3