From nobody Fri Sep 25 12:02:14 2026 Received: from mail-lr2-f12.google.com (mail-lr2-f12.google.com [74.125.230.76]) (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 332D73016F5 for ; Sun, 13 Sep 2026 03:50:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.230.76 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789271402; cv=none; b=AAxzDQnvbPMUCmy6zNgTWt9jmBOe+GSecZsrl0grF3wb4wnt3Ev9g8zLwM6i2wYBltMTN1hTLxEud0eUZXlT/QLjpYQgO57AJV0Dd77T1biO/FpZ2WJlbMOD9nxwOG+R+sqV3ExKaxdBrIMjsHKomPKTxDS9IRlMKZq+DF+FnhQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789271402; c=relaxed/simple; bh=59WxsqcOX2L2RBvv5RmjuUVbgHr8/VHIhI1MMHeZfPM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PiXuZIWw8DvgM8XK1j8xjLXcOHqw4hNi0uy52v7XZR6QAaZjIeph34PHc4HAhdDG8FbbQsQ7QWMmxEVTj62P77vXG39eudLVKE9cb7puGNRXZ4FWWYyutFUu5fpFEliE4wLeE7Age5Og/pNBzXaTGRKURIuH6txEagA5AenNfUQ= 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=hEuaMmoP; arc=none smtp.client-ip=74.125.230.76 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="hEuaMmoP" Received: by mail-lr2-f12.google.com with SMTP id 38308e7fff4ca-3a2ff163f65so6553731fa.1 for ; Sat, 12 Sep 2026 20:50:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789271398; x=1789876198; 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=DAfpRG4RgjzEpNA/SBmwyiTwL7l/5J9GMQEmcjE9tJM=; b=hEuaMmoPvcI2iEVvCFAgBP4/W8T1XqI6PO8VA9fKot9C8RO8qQGfXma+/uYqgxwwsg isFk3hZezK2WIHsrqRJO1Wdssxj69mrpO6tUh8mcdBvE9zc5ahPgHV7uVfRaVPWbGW70 TmYCgIaWBcGQbvvoXgQ8vMpZLtzmhY0WdwZbfR7JOtaxC8fsHLaE3c9m20Oapmto5Wd5 tFz5xXpgbh+k1C9gLc187rnhgfA527ftG5HVKSkD3/BR9+6VG9obrcJrE3fk6ktzJq2Q FptLxEL11aEajqyBNZyW/h02T25WfAhyvEIVwwRMBnXQ6lTfGgLBJjvk0kLwkHD9Rxzx ge8w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789271398; x=1789876198; 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=DAfpRG4RgjzEpNA/SBmwyiTwL7l/5J9GMQEmcjE9tJM=; b=WeoJlS35Duq/ud1a+qU21nSM8DvCI4C5vqWRL/JDaBK09M4YLC7M39HaeCHA0AlYgg +2qTXLev7Dp8jMJYboCRDc+nWsNm0QlwVG14mG1DDUHagK+93qYEGIUjZ9ApwJg9i3B0 zOzQIE368KqFFAoGDbB2oWh2uvnVvs/h6vZ2ostDF9vaV4Mq5B3U7tpANNh4jm6eDUHp N7F9/NhkXBX53bmJucWOE7jSj4fqgsQgrlLgdbl6wGViQaDLqJxbIrUK793cj9rWA8KS 1XaTvHgbDjLfyGJ3l5HFP5TUypL2UzVTehAkPdu3znZmSW63W67oB3aMUX8ygXCHbmcb xnKQ== X-Forwarded-Encrypted: i=1; AKwUvBxtKPvqDdsBmQlKSx7gk8/CovJj1W+t1H/2ruVir7SPvJDUk097R4qt0XJ7QnTWcv5SgdX5v06J/jAmg8Y=@vger.kernel.org X-Gm-Message-State: AFuF++mmpG6UmCLGsef+6QE4VTfA07YiLS3kYTeSnH1/A68ivZz+/7J9 rYyiaHd4ySiTTQZBvz1RZvOKLWbYxsMq5ft6/4e4vtBPOEXaofOgJnYn X-Gm-Gg: AYBFou26Bvj3cU2kCzmvCgtxig98ZvmnLJNzqLRS5cNE6wfcDLd5msHokgaQ2vhxHug Ij12OjqnNPbRwnfTP/dhc3VFTD0dwI7WeR8JDuX9sFtPvJkMeu/K4Ya4DzkRWlIjy+NXKV6KFol VsQtXzxfX9h3ZlgjKyk97YqD9kP7rNMgDo5ak4aXnJPx5IBPQKfJyxv73/+LpuLrdUuQy7nq4HG buPSByz6fQOI1deaTl7bvd7a4N1ZvLrT1NCxr6QuyK69lG/OFgZDHe0AR/wcRZERV7/WTfbyYmX p6DDi/sZuQZmcdM+Rqzf98i+gmAjCYZPY/gWefxwM81+UAwLzNO/ek5Dy19rT1Kyx0jKsBYuNur BtYr1OhnqRwHllNeSeHMvA1a0vMuzoFVN+nN04Y6KmVH/PtZRjS2nebdsvM6n1eWh86pWjlVLvI +HaWyTp+hvIN1SQkfGwbPxN7WesTcw5RT5O4kpbhN41+UkDbQp46n3gAWBtlxjTnsKMEbvT3/JG R5TFAleQKoP+wtQlpfrjP34A/jgu8qEfjWga2mQla0J X-Received: by 2002:a05:651c:19ac:b0:3a3:2a41:c0c4 with SMTP id 38308e7fff4ca-3a5b37efbdbmr6428221fa.14.1789271397883; Sat, 12 Sep 2026 20:49:57 -0700 (PDT) Received: from dau-home-pc.. ([95.139.134.117]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-3a5a332737dsm17277051fa.22.2026.09.12.20.49.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Sep 2026 20:49: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 , Ido Schimmel , linux-kernel@vger.kernel.org Subject: [PATCH net-next v2 1/8] ip_tunnel: add drop reasons to the generic RX path Date: Sun, 13 Sep 2026 06:49:30 +0300 Message-ID: <20260913034937.875068-2-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260913034937.875068-1-littlesmilingcloud@gmail.com> References: <20260913034937.875068-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_TNL_OPT_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_TNL_OLD_SEQ is used when the sequence number is older than the expected one. Unlike the previous one this is a property of the received traffic: a remote endpoint that restarts and resets its sequence numbering has all of its packets dropped until 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 12f909651591..e1fdd11c939f 100644 --- a/include/net/dropreason-core.h +++ b/include/net/dropreason-core.h @@ -129,6 +129,8 @@ FN(PSP_INPUT) \ FN(PSP_OUTPUT) \ FN(RECURSION_LIMIT) \ + FN(TNL_OPT_MISMATCH) \ + FN(TNL_OLD_SEQ) \ FNe(MAX) =20 /** @@ -612,6 +614,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_TNL_OPT_MISMATCH: the tunnel options + * carried by the packet do not match the tunnel configuration, e.g. + * a GRE tunnel configured with 'icsum' or 'iseq' received a packet + * with no checksum or no sequence number. + */ + SKB_DROP_REASON_TNL_OPT_MISMATCH, + /** + * @SKB_DROP_REASON_TNL_OLD_SEQ: the sequence number carried + * by the packet is older than the one expected by the tunnel, e.g. + * after the remote endpoint restarted and reset its sequence + * numbering. + */ + SKB_DROP_REASON_TNL_OLD_SEQ, /** * @SKB_DROP_REASON_MAX: the maximum of core drop reasons, which * shouldn't be used as a real 'reason' - only for tracing code gen diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index 13b5e35e8790..0260a97e990e 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -378,6 +378,7 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_b= uff *skb, const struct tnl_ptk_info *tpi, struct metadata_dst *tun_dst, bool log_ecn_error) { + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; const struct iphdr *iph =3D ip_hdr(skb); int nh, err; =20 @@ -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_TNL_OPT_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_TNL_OPT_MISMATCH; + goto drop; + } + if (tunnel->i_seqno && + (s32)(ntohl(tpi->seq) - tunnel->i_seqno) < 0) { + DEV_STATS_INC(tunnel->dev, rx_fifo_errors); + DEV_STATS_INC(tunnel->dev, rx_errors); + reason =3D SKB_DROP_REASON_TNL_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 Fri Sep 25 12:02:14 2026 Received: from mail-lr2-f12.google.com (mail-lr2-f12.google.com [74.125.230.76]) (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 84887384CF0 for ; Sun, 13 Sep 2026 03:50:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.230.76 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789271404; cv=none; b=tgRwZfdA54Gw1U2k1Ljm+uBd84bD2QxTQFquDXplhc8fCJc8lRFiwfioBIeSYWy7vAWog0oeo/kMm1uKHhcv098bj5H7hUKYIRppKChwSAHPFqG/PqsHZ8QIGirKt/UDo98kdmZamBy3WTL/+CzQeka7SUUTIYALhEtHVosNBXI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789271404; c=relaxed/simple; bh=o48wrWvjoIliI06ZgFy+hiyAVOP8nZdeFGGfqhQTNCw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=K0dl8AoKWW4SK72Rj5yczNh8EspAn3n2TRB7A5UpMYKNezY7JObTi14ynVAdRQ+uXV/zK5NsHTgUZZ22jvbUXW08edI03x1tmKaTk3gEsHGXoFvVbpi3oA+T0q/yY2oi6ytgtpIg9dd46BNeguZfZexpgRnEp8XVNQ3FRQXEfV8= 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=bcNHpHtq; arc=none smtp.client-ip=74.125.230.76 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="bcNHpHtq" Received: by mail-lr2-f12.google.com with SMTP id 38308e7fff4ca-3a35a64530bso7642521fa.2 for ; Sat, 12 Sep 2026 20:50:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789271400; x=1789876200; 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=unzmUg06rWGBT2CRAbdUbshSQgFHbsBrT0vOi+rL7PM=; b=bcNHpHtqIBFY+JEfrqPVpPdQdKESsbsRs+EVNR7zKJ3+ihPYuMZ2OzG+9TpG4V66c/ LIH5nErmecw8FR3s0lNE17gFinLshTkx/W+psYj6/ILnMXtccOf1llnQsQ4bjHWRkWt2 BYiKMLFSk+J6vpOnZd5glpFJ/8AI8GLZDC2rFS+iMIRl/nETsAIg6LBWSiB2VKE4yRo2 CnE1FECu+Uup17In88/txbvausTWbu0Hgwxd/YFvzRdvf1MuJZGB5ZSwhBMzU995gzCd MV076IFe3mFmg3Vnz1jElwF2p0QtVy4yYUGDq6IjtBRG/P+2/myD43GD20SMoR5E6pU/ heCA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789271400; x=1789876200; 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=unzmUg06rWGBT2CRAbdUbshSQgFHbsBrT0vOi+rL7PM=; b=Iwm+M3YaNt8qoNaicisSgu4jpfRNe+BW/blptYYZHzwQa4Uq6qyBob8q2WqEQeE+YZ LPF5Cgh7bGPb9jBRiDvLxtK116lL88EeCIM3HhhctzgHve0+gAk2XqFutEvgXdY7rrjR llglUXHKt83g65XiWbHdWhP9CLJLbSQ0y/igEA5wFL5bFQ78XsMpr2P3BIFjesK91QIf lnQB5oFcKD5CuPPiZffXKgVBRNlnIm6FTP4ahQ6m8Y7J78/CigLYayGZet0dDd+1RjwQ 3lTUMZtx9bdcmRfgno/3aNu75dgDcuZZk6W6muo2Dcfi2GAxpPtISicAxhaak6p2WstB 6R0Q== X-Forwarded-Encrypted: i=1; AKwUvBwJMakEZV93frEYgC2r4a2FfgM4FV0+kITGAdjl142FZWAwTmnNqXZj7VjKdiOIm0MigqZ+z6u7dmezki8=@vger.kernel.org X-Gm-Message-State: AFuF++nUiDfgbQphh5rak8ko8C5rkJCc3U53tSVlbe+m9VXR7bW4MlXm P8i+8jsU04EHD7+kOiY/El7uwcviyEDJTM/gSxbBrFMwQ/I7j0CWXK4Q X-Gm-Gg: AYBFou3zFHQAYrsyNuTfEXMLjvztsJCkFw21TA4MlR9GbGRvF0RqL3RScHLvXl3PRGb GmB0JuYweoPddN2u3/r9GZtvWstzmJ69OhsFl9VnaqBxj0tL2/se1xw5x33ZPFwbpMyzV3SYRyS v9YcxF58QLzbyZQH0wh1BQYlonftKNj3yRd/5P9gMdESZuc+s4mvdYmu8rv/9W37s3QfDxVgKfT KEMU0GD/flTfm2g27vs3wufT640mGBfpzNyMlsPqX3jWK2Nc7ZK7MXxAKLQvTop0V6qSuN+vE8J vk2obkR9irOTvFcAP1YIHm9fkmc6RmCbHxAcrsHCq6ARwdDl/0yJrPjo2C/uRcNTCJiKLsCcbNl GcCNlRkVXQkm1F669dCKn1j6wJ6hqO+9XBSapOtpj4avtQbVqjKsPYfunsnEB6dJHZdlf3/q9jw y0WMfm1tndCwMiBKeu84mqhklTBFUIWxDZzMb3j56ce87T0+bbuBuVgyJDaenFCaHEpopAjB7ui ZTOgi5V+5djsyqzQt4FoZG9kdAcB7+jcQXp7y+z5hjP X-Received: by 2002:a2e:9a15:0:b0:3a3:74b9:8a7a with SMTP id 38308e7fff4ca-3a5b382d744mr6509791fa.19.1789271400106; Sat, 12 Sep 2026 20:50:00 -0700 (PDT) Received: from dau-home-pc.. ([95.139.134.117]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-3a5a332737dsm17277051fa.22.2026.09.12.20.49.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Sep 2026 20:49:59 -0700 (PDT) From: Anton Danilov To: netdev@vger.kernel.org Cc: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , David Ahern , Simon Horman , Ido Schimmel , linux-kernel@vger.kernel.org Subject: [PATCH net-next v2 2/8] ip6_tunnel: add drop reasons to the generic RX path Date: Sun, 13 Sep 2026 06:49:31 +0300 Message-ID: <20260913034937.875068-3-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260913034937.875068-1-littlesmilingcloud@gmail.com> References: <20260913034937.875068-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..458ce328311b 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -813,6 +813,7 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct= sk_buff *skb, struct sk_buff *skb), bool log_ecn_err) { + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; const struct ipv6hdr *ipv6h; int nh, err; =20 @@ -820,15 +821,22 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, stru= ct 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_TNL_OPT_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_TNL_OPT_MISMATCH; + goto drop; + } + if (tunnel->i_seqno && + (s32)(ntohl(tpi->seq) - tunnel->i_seqno) < 0) { + DEV_STATS_INC(tunnel->dev, rx_fifo_errors); + DEV_STATS_INC(tunnel->dev, rx_errors); + reason =3D SKB_DROP_REASON_TNL_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 Fri Sep 25 12:02:14 2026 Received: from mail-lf2-f12.google.com (mail-lf2-f12.google.com [74.125.229.204]) (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 6626A388379 for ; Sun, 13 Sep 2026 03:50:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.229.204 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789271405; cv=none; b=stiA5Rr7SNBB4jPk++W2VMTROJcE9WrxWUyEpGWMIx4f+8O1iz1DK40cL9CE5n5EvjDQUTB17MsA+ZJSqq9zd5X55DoPkiJw7AurML8sl4XH0czQuN/uxQ1NZKiJ7AUGd+S9P/9DGBy2SIuL7dC2lWoBwLVM6AV+CglZ9VFgCKk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789271405; c=relaxed/simple; bh=GO6Gw1A9juIU7UQK+OBcuOBnE+LaE9NRP/n52vmI6Ds=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=RIGRFfnu4UUGj8XXdeR1hPwOu4DDK5/OjvEoV/WjXaYnWyLljrTptzjkuLwsK2oFeNR1fpNZDwlwnH1Oit3vNd3PYtsr71BvO+sXCqVVN8S+ZRlWsdr/n8yo8Mj38e9+CUoZgWCaekzUyTJfcTxXokEm959TFYwtMeBk3PEHvnc= 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=YSeG4toG; arc=none smtp.client-ip=74.125.229.204 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="YSeG4toG" Received: by mail-lf2-f12.google.com with SMTP id 2adb3069b0e04-5b5e4f1801fso1555285e87.2 for ; Sat, 12 Sep 2026 20:50:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789271401; x=1789876201; 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=bWSE5/EbNePj/bzNdrsb4KiTqY/RgZxbZLpv4ycdu5I=; b=YSeG4toGFgM5X9pe+PWpwVc2XD/T5GDmBDgsM1KVUvbmFi+TqKYESk0SuB4Z/jrCJj Q+fDv4XkKKvvqs6UVyeX8ZJdiH34TQSW5jndVz4Zp5NqgFoEskcIh7+iIotuYK8pckyC TZO/ANqbXTJ7xplJKIWE1E9N6G+oup8/rhS77SdEDnzNdIYPAXGaPYk1KXggJNei50i8 a8FA54RcKSIb/GunbJ1lcUEBwJC466jDvpgxk4qjG/cOi7+8FVw0UkQJQnECgyBDP/9+ Ydd3JVQqKhTvlQIBkqtq0d8azA0owFq10Xncfxpn6rHy4luMjFgJUx0pt7EV1+hrutAS vZPA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789271401; x=1789876201; 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=bWSE5/EbNePj/bzNdrsb4KiTqY/RgZxbZLpv4ycdu5I=; b=jG/MzYF9hcg5T09ZwqQJlJJ+MzGr83hw/I9biFDNju9sYXbM1yTQtsdfwHQ7Z7qcSe y3eAddlofixHs4KebDP6w50rpOIq3OLzU1vjeaFDmhSbUf1k9tpn5RCGYB0SgCZd2+WB 5000cvKboyt6euvbNTC2BMWabZAmC1ZEcWUVlhddwTPLn+CiAtA+osgPh/hPVAVJ07zG aDDLXWYV3b1zcpbc+LfHEZgPqsRI5TWeeItb2HkskP3PDeOHGtRTtEE+4L1fs4zunNvh Ip2lGxG23lEHPjYnRsyD4CnA0JxaznTZLGNIHkKjvkMFZNUKo5+ftHnRmIhQ1Uz3A+Ao 5UmQ== X-Forwarded-Encrypted: i=1; AKwUvBwULzdSbGSr/IBXZUQISksvzqljdVEfPjrcif9QqDetTo/xxNmKQpuBzVW1Hdmf6jnMjOW5BtgxA/FICMc=@vger.kernel.org X-Gm-Message-State: AFuF++mvq6YMhnKFE//5oCYFW15/00xtYA18sOtGInAoypRHFFgRPKK1 hhxwd2EhWAbK09gy/Dt8S6PAGy7NYtz6r01TiHD+fsCWoOy2vH9ukn0f X-Gm-Gg: AYBFou3zEc7bNemiVUnxnnysEHHbZYvhn/XfInbiIqn280gVaSQ2V0PoBrWhBVWGNiT XqcqIxsf0o5IReKYrBueZka9ATMDKUFUPn2jt+/pVCe1FYs6pjrRTZwlr2ZRYLq1R877pU/B8zi MZcZwp14EDlxYVIjeh8OKTgGYZ2uZD+Da4qFFSgbSUgiDh599Mtl8bPU8VDXGUMhVkTcdKJX9nq K31SteEMFYbTkh7j0N0Hy/4praoYQeySO3l9jFKCrPPvywEbfntkBKI4QmyZZkxg6YJB3782sEw 6wFhWWYLqaGStGShyHiBmYebjP1i+u88p1DkBWA1j8ne7enKMqkT8um9okxlBD97kgFr57tepPp ySA3xyHAEHzssqAeRqsSzbpkDmtEEngnO18JqgmorEGc0KjmA5Hez11/gjDD7I5odiyOzQfzoB7 Fqfs26bX/S2pQqDOPzBKygqWMzlfMaR/u+Nfz/VCk5CDdzVe4fc73q8HOXE4R/GW9F+YE20c/VX 0J9UmNVHoVlZX3ciQKuoh9cJNI0472iGfS6mBo8holaAAQrkHqB5o0= X-Received: by 2002:a05:651c:222c:b0:3a5:9bb4:cc2b with SMTP id 38308e7fff4ca-3a5a523f81bmr12563451fa.14.1789271401146; Sat, 12 Sep 2026 20:50:01 -0700 (PDT) Received: from dau-home-pc.. ([95.139.134.117]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-3a5a332737dsm17277051fa.22.2026.09.12.20.50.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Sep 2026 20:50: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 , Ido Schimmel , linux-kernel@vger.kernel.org Subject: [PATCH net-next v2 3/8] gre: make gre_parse_header() report a drop reason Date: Sun, 13 Sep 2026 06:49:32 +0300 Message-ID: <20260913034937.875068-4-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260913034937.875068-1-littlesmilingcloud@gmail.com> References: <20260913034937.875068-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 e1fdd11c939f..6ae7a604722d 100644 --- a/include/net/dropreason-core.h +++ b/include/net/dropreason-core.h @@ -131,6 +131,8 @@ FN(RECURSION_LIMIT) \ FN(TNL_OPT_MISMATCH) \ FN(TNL_OLD_SEQ) \ + FN(GRE_INVALID_HDR) \ + FN(GRE_CSUM) \ FNe(MAX) =20 /** @@ -628,6 +630,13 @@ enum skb_drop_reason { * numbering. */ SKB_DROP_REASON_TNL_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..efd5f60a9c59 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)); @@ -145,16 +168,20 @@ EXPORT_SYMBOL(gre_parse_header); =20 static int gre_rcv(struct sk_buff *skb) { + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; const struct gre_protocol *proto; 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 8ebda0b6a78b..78854cc2dac9 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 Fri Sep 25 12:02:14 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 C23D838B157 for ; Sun, 13 Sep 2026 03:50:05 +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=1789271407; cv=none; b=h/ngefXKlePg2t9kE+Ei5OK6nZxdAhjlqjA2cMX9I57SJXJKmDNdXCS06Ngq39MsH9HsUEitr9aBte9WEvdOJy8k6eGxgwUcFGeqc6O3LzGGAh1yU4AnMO5YqZrzeZB9p1OScf2RUl03o8hubLOULvekG/eObzFHorbfK+yyqQQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789271407; c=relaxed/simple; bh=ICJykrUcFsTqZGtDXT59rk7AoFn2/RNxlEqe44411RI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=czbAWclMHuh/MDgircPJ/c9Yxg2wq07a5vQuRiwu0pdazSHJzrazn65yW/yDL9EBXrEntxG9SOsPTGz5tiIl1kyq+VuTM0KlUeansbwWgNYCOH3b5MoyzXWk89Cg3HjxfEMYny7CzoDleR8qkSEZVuSrgCiI3WGSrfSNRf2WfZU= 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=b9oOAW/Z; 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="b9oOAW/Z" Received: by mail-lj1-f170.google.com with SMTP id 38308e7fff4ca-3a33307ecd9so22362801fa.2 for ; Sat, 12 Sep 2026 20:50:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789271404; x=1789876204; 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=txCUeYmpqirgtdt/tYCNBsfM5AynCHOCui/THIn7RvE=; b=b9oOAW/ZCxWvvWGIi9KJFmhsVlL5/SIBdYOnnU16Z634ajs/edEG+LIpYXDsszYgti ofiucIM90bLI3XtysUkKGHRaMR/2K2vFymCV8VXJU5+KRZYO+Gt4UISHGTiz7oZb6VAw qvXS4jU86OPbjA3HUY/k4yiozzQY9sM4DFwaUvlvpBsTYtKmV31MxW4n13JD71DUpz5V 6VMtKHauozzVNlV0btrX7uh8Ym/zeS9b3i0TFCWgj8u0mQB9k5Xd1aa1lQzMrfGc8aKl kHwdD318tL8rJo/fuRJO9zLQJQyQF83kPOxs4cHyf1G31j00M+7IV5VGW+zHrrc5eebo uWtw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789271404; x=1789876204; 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=txCUeYmpqirgtdt/tYCNBsfM5AynCHOCui/THIn7RvE=; b=jVvdNr/3DS+n6QM77KtCrX87LawyhA5mIMsfjCyHoQc3yZzBrmYDRBMolHlzPQrmqC 7gVwdTtdMzt32u4Cs5K0vDenWW28np2X1WzxXW12VjYx1FP/+jsVP7LVReB1uVEg8rBN qi/SXTUToxNTM0s+FULeul/JNqrZNfjdbS7dk9NG+swpxJlzBsEONws4TBPZTgxdiO6U XqV6w/Y9XWhJqM+5Z5AN9iAxxIz+M9aGrib/+gFiVAznjiG/OLzJJHcUk/I0fqDquZmu ld7VC590OcWaJQkRrY7lPBJ14YuTLbcvNLcjOXMYmqLr6HR4YaB3k3t5RxJTyQDPj/xm vHLw== X-Forwarded-Encrypted: i=1; AKwUvBxDZyaS83y5XVIR3Y0LpR4ATadcfNeUz6fuQTZVqAEJy4ylmHWCapyWfx/WonWYDqp48i9lmjqbzcqRuSM=@vger.kernel.org X-Gm-Message-State: AFuF++n7tkovnu+HyVE45DBQOqkljQ/lhjPs+UEEZtqTdn4D8/xApu1p SN5zIUURjXWv92l2NpxR94xaa9bsUqBtOGVcYHGQH3XYJozAUXRbzabt X-Gm-Gg: AYBFou1cdts5pQrxdaVmEZZ+RmTpwaEEHfczpOd6iSwoBbxz2nDLu4HN4tev6TcVeaC 3mmvC+t3DXP6BXm285CmpBEfgtg5OSmVqfVzP/YJtPlTkPjqwHox1xkUW8sf4Qm1XwxNtYxxeB4 Og/HrTzLqsEe2nG9jgWh2AWxZxmtAV4gacpzydobMo9LsBjAqxVFth5nh4q4bmGovLBs+LSEB3O PSwqdaB7vNT5c9yw933uRWUHLmW5qTIRenNp5lFQ82QA4MXN7V6m/LaGTeCfbz4+5HXciyProt6 QKQjmmhNTpAZ3HpqTWYj4OkTtIhJ+1hGPhV9v6P2Hm2VVcf1OXUi3gNV38fUSu3GvOVO3HoG2R9 MYg5wlxC/QXy2E3N/AeHEmudHly7eRdhaF1IKlklBodcnvPXpBdFKHz/VUdipmFaw1iMUoud8Q7 tIt7ysuWo72+UTePoF6Z7KJtCdgCzqNzL7qn0hYGV1zsKXqYOzwR8A5nS+VsqRUmZV/oiryqeQv FIrZlGaETxxxSpYfizMHNpH3aEXoFqNihJjrLBJqty1 X-Received: by 2002:a05:651c:31c6:b0:3a3:4c63:771c with SMTP id 38308e7fff4ca-3a5a5208f2dmr11451881fa.12.1789271403456; Sat, 12 Sep 2026 20:50:03 -0700 (PDT) Received: from dau-home-pc.. ([95.139.134.117]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-3a5a332737dsm17277051fa.22.2026.09.12.20.50.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Sep 2026 20:50:02 -0700 (PDT) From: Anton Danilov To: netdev@vger.kernel.org Cc: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , David Ahern , Simon Horman , Ido Schimmel , linux-kernel@vger.kernel.org Subject: [PATCH net-next v2 4/8] ip_gre: add drop reasons to the RX path Date: Sun, 13 Sep 2026 06:49:33 +0300 Message-ID: <20260913034937.875068-5-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260913034937.875068-1-littlesmilingcloud@gmail.com> References: <20260913034937.875068-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 6ae7a604722d..fa8bd552122f 100644 --- a/include/net/dropreason-core.h +++ b/include/net/dropreason-core.h @@ -133,6 +133,7 @@ FN(TNL_OLD_SEQ) \ FN(GRE_INVALID_HDR) \ FN(GRE_CSUM) \ + FN(GRE_TUNNEL_NOT_FOUND) \ FNe(MAX) =20 /** @@ -637,6 +638,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 Fri Sep 25 12:02:14 2026 Received: from mail-lr2-f12.google.com (mail-lr2-f12.google.com [74.125.230.76]) (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 2584D38F654 for ; Sun, 13 Sep 2026 03:50:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.230.76 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789271410; cv=none; b=NKl5yE1BO52rQKw+2vM5dmerV0TNN5Om1thPyqYEDGRRk0/6djVXFrIgscrmjEhZevr2vZuwgoIt7l6mybt6RsP/97KQlOFOuBqrv1X8k0FfFMUouYPEOugq7erUlwkBScU5tmjCl3/LqCueSu2IEmsBFq2FpKNinGqle6YEnJ4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789271410; c=relaxed/simple; bh=/D5+jnWrGXf/9Ql4Y4axRz9xJrB1SxATj+tGKiu91es=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=RfimAyL6W15qwgMN/N14LrrDUGslUO445OqDAY+UXKL0rWs1RU0DWZVYVXmP5/Rz4Gvh9F799WJSRJeLgGkpK9mQsd6HLZFlO9lZ4SapDaaq3xFq3jBgspewppb5xYghA+HyzA72VLaCT5OEQMJ+3mWOp3RmVH5PZZAtDKNcDHg= 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=YfB+0PjB; arc=none smtp.client-ip=74.125.230.76 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="YfB+0PjB" Received: by mail-lr2-f12.google.com with SMTP id 38308e7fff4ca-3a49a10ee5aso5821591fa.3 for ; Sat, 12 Sep 2026 20:50:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789271406; x=1789876206; 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=s5kc/PoxLnieZdrdEa77M8eaMfDxxTd0DuCYS/9794A=; b=YfB+0PjBaHhwhYTXye4pgTWDj+v7qXtkeYamsuNWudb31ngXa1NFn6NiFG5yxTIHw9 HXjEIUe57IKtUtjga+c7l6oUKvd9V0VPy1X41Ck/h3Ba1otONBtZSuaUhlKb8zGGugq3 1BDBXkM1ygLvulCe7p0j5V/O26/6Og6K8Qx2esdOktN34jECep6M5XQWljNSUsk/va4l q00UKUFKbOGfJP9xzCiYc1g72MbtcBO5GIachxwbBL/a77ZxzlyRlqTECxFqU8P6x9Hs JyXjeHN1H+BWiv4NFHcdGm9m6cBW4iRKK5FJdCiieLIX7GHlSsIRJqEU7uCONLZmoLXW kC2A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789271406; x=1789876206; 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=s5kc/PoxLnieZdrdEa77M8eaMfDxxTd0DuCYS/9794A=; b=F6skz5xh3d9kSBqBFvLLe3BXaTLyicTE5iugRwjDk7IE33WWgrt8FzOezs9ZjPLTYN yVDQCB6sKVtiEQ45M6VApc6pRk7fdtt8FBDDX5ywDgA6qQlE1uztwxnOGw9hcepaakQj +ebxA5zMhVAWK2KYA1FznOV25eiK7CHfjfaZpfTizlUuuBofzyBGYtrfCK09/WIOMIs0 IMIXkd073A5eDM40TuPsRbS2968OjNe6EOK2GeG2v7GCMc4dgj6Kn0fJRNTQSDJYY7kT E3ygSatTYwKMWVeuYxrR9aUzM7jg4JLRLJTAfltvx8ryZgxTFQgCdRP3VvXK/2h8Cq70 pjaA== X-Forwarded-Encrypted: i=1; AKwUvBz4SkrevJldUTdbmDKuEQpXnMTUyjrr39MhS5JwS0tppSDwTicMikwkJI6TkuRid5drwkNASV4M/Ob2/50=@vger.kernel.org X-Gm-Message-State: AFuF++kdVy+OiYOm9PfAJRbOiSnZxuWBeXqlIUURwDbs8dQQH5/Jfl6m ThlDtWPB/Erg+v13YmU9xzOw0E/far4A0thjclagS2/XvP4wGfmFdw/o X-Gm-Gg: AYBFou2EajYOsnA6UEaiT+QuE70zckiZqtO3c4B5N3uCok2JMzyD7ni0ANC3fodtASc 0PU+IljF2RzZcFMkEtgPExCx4dqAz1GKQz3/hU1FoNmHxF0eJImIDxRaitwNKTfnSaeCj8Uaj1O Da4SbA/1WkoA4TVuf3ULoOmLluuNRhVvUAXEr3Oc7yXO0unftK6yH1adC8SobakqJq5Yt/0eWlL Eb70R6Dxk45MMLbxc13mdJE9BSkK00GtoC2sMBd2XYwUoliYhE55unoFukeYaz5hoAqakyy2zr1 RpEPDZKWtZpujmmdLltqiF/L+1wQhMxZWlLjqLSRYQ2Z2tLVyfEnZHSzBNCo3Ax0guwBlRpzjUn kBN2ooFA2mpV+l7shC3pYDCOjK060Bj06JsH8bXXecg0ASHIlNg6dBZW4IyVtUEmFlLBL0+5Fdf GejYhoJUdKv0bsXsiFRSy2QfLpuzW9je8ob+gcdmO42MoY/U6tqpxp99M/WfdN3qnR/ysMh9czw 2kcbLb2RRQpyxZzZsMm8yp77sgYakATc4/pwqXUgbY0 X-Received: by 2002:a05:651c:2124:b0:3a3:7681:6d66 with SMTP id 38308e7fff4ca-3a5b37f2198mr7053411fa.15.1789271405968; Sat, 12 Sep 2026 20:50:05 -0700 (PDT) Received: from dau-home-pc.. ([95.139.134.117]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-3a5a332737dsm17277051fa.22.2026.09.12.20.50.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Sep 2026 20:50:04 -0700 (PDT) From: Anton Danilov To: netdev@vger.kernel.org Cc: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , David Ahern , Simon Horman , Ido Schimmel , linux-kernel@vger.kernel.org Subject: [PATCH net-next v2 5/8] ip6_gre: add drop reasons to the RX path Date: Sun, 13 Sep 2026 06:49:34 +0300 Message-ID: <20260913034937.875068-6-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260913034937.875068-1-littlesmilingcloud@gmail.com> References: <20260913034937.875068-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 78854cc2dac9..047c4f57a828 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 Fri Sep 25 12:02:14 2026 Received: from mail-lj1-f177.google.com (mail-lj1-f177.google.com [209.85.208.177]) (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 52651390992 for ; Sun, 13 Sep 2026 03:50:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.177 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789271411; cv=none; b=XZ3M2ZSSQCilEDo3oZxT+oh0c0YPiefBy6h9KJzpP8fF594nuqi5spR52wCMsnvpyExBM1bWLZzS1rCOGv5p7a/xCtas0tLzWNEjOnGblyIVFov+0psy3371r5k0dCZDm/F9cY8NzoeFz+4FjYAqEt/vEqqs4sjB9uOJCCQMY6U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789271411; c=relaxed/simple; bh=zft4siIVzjvwyrjp+6cNDJekjhXf5b3vJKbJg5NmvCc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jwuY7oAfVJRoDx4y6GB46IqnwEPqpxSFjyKUgV5s/bWijYTGn69UlqOQ/IPyeHTQorx2BLqAKOUrLvlId0lnoXKcVr4KQV65kBaWF1gC4Go5WP+rV8qTbtDzbEriJxVxfkK3k6/DE8iprcl0/fX/7tnowqg1H1TWWKzloGBztso= 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=XdDOiiOh; arc=none smtp.client-ip=209.85.208.177 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="XdDOiiOh" Received: by mail-lj1-f177.google.com with SMTP id 38308e7fff4ca-3a20367cf82so18133481fa.1 for ; Sat, 12 Sep 2026 20:50:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789271407; x=1789876207; 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=sQJgSVahL7et4eCG/b1accUqaKciLG+AzNANVA6kd74=; b=XdDOiiOhblRMkj5qOmLBaORodOVW3Hli+BNGEuH0PMQki7C00LYbY2A5PWo+XTSprJ HYWnpZUq+sORe8VwMvNuN2vdaX4hZU6WkH7Gjd6sSHYJEgDGQLsQF/wyxYP+odFAHEeN NLRx8XRsY7X8e8faGZA1I2rYXvGZWBOXk0S9Fiejs92ftyW8Okoi85QRrypXIfsa3Hnm DVRyu/QSiEn0cl1MMiCvkJ/hCUjzSIh/xUVXeU/Pw2M9TFkAdlgN5LMbtVL6M0zKPTPi 3sD8bZ7BikNKgsDdx95EAtpiDjEX81beMr2wSQi6q48keOokPRipWlF5dQX1utF5/9qW SrvQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789271407; x=1789876207; 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=sQJgSVahL7et4eCG/b1accUqaKciLG+AzNANVA6kd74=; b=Xn5JcG9J+rcXlVPlkOyoEQI22uCbsV3l8Pw2/QvMhdNDb/YxI/zrYtOe/bjaEfo+by JfUo7ojsDWqK2Skw/wpcI78RuHfB8YjXlZ7NFpbjvzsSaZCjVoPnWzQcIRj9OYZmuHYW dbEVvZA7LYpGb5g9SfCPz5Vy4gv1sK+vJcjJZ0g0r2yr+dNuOlUJkbYyG7yGXl74rrh/ WapSMmvWxMpzUGfU5OkUoh/YWEWCGWhorskkapckL09yUVt4SHtxp5vG0lz/njLdCjXO Ex81507B/Zai3wMc+Khr4npB/ndDGrwCog4XcXiukGFfK1hKJkHeGinHGl3LvVZ/DZe9 CGfQ== X-Forwarded-Encrypted: i=1; AKwUvByi/SwwEOlqyAAvrv8Dqj4wSTiIogIv8OoPu59B9myzmuZ8RSJUFxg7oFVfiqNrx1oV+RhpE12KTOfw/HA=@vger.kernel.org X-Gm-Message-State: AFuF++kcw/HTh61grfh8YDZPx3a8tO+0k9MHwUmlhUWdmac1esMnOybo FkvIBr4pzqTFta/XeG/c2boRPco4FT/2RXiQhFGu0C1plet+CFxw/Nhw X-Gm-Gg: AYBFou1P2u6v10D1hLQvnk307cNavL4ZQ2T4CBl0bKentBCvW6cT9WC5Qb9wyaVdWMf zkkCL8WPBIuOThpaX7gEkKMCyQKYHd5ahDJXhwdltk9qQFxPpu4RhkfCAH1C+BqAdGi8FujxVr1 itHE/HOxk8RIds2LcUNMiNpeNfP+DBF813MDx73EzA3ettaJ8zRN7Uwo5vY7DKIaDHh8mqRCyBy 6jX2Cuo/dmnWNXIR3TlfRzXwTG0aycH8aXzzflb59TYNYsmNnj1MaJSP7GD99ul7HasDoPKzeFi kRollb8e1V2M4A0zmudzL3LYISvHK6PbY8Y7f8R7nRZ+UDJszOBxFZ/DslJ9hFzXBGiD0k8xCEo VSaWeNo3uIWgO1MszozOZcLn5FVpCK1pBfL2m0b0yfMwqOsg+TjZr7chNF6Ya6bzIDOWybxbOOB g+3n4ptySsF4F7Ff26X4wd683wSen0qW/2o17bSrtWEB7NFv1UN1IRtnFl6cxrUG5nawCRM4VtT FFqgYBgScRyv6OtTUkEkCjH3Ce081lC/Kp3Es8pE41F X-Received: by 2002:a05:651c:a169:b0:3a2:522:c75 with SMTP id 38308e7fff4ca-3a5a4ecaa35mr14204161fa.4.1789271407042; Sat, 12 Sep 2026 20:50:07 -0700 (PDT) Received: from dau-home-pc.. ([95.139.134.117]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-3a5a332737dsm17277051fa.22.2026.09.12.20.50.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Sep 2026 20:50:06 -0700 (PDT) From: Anton Danilov To: netdev@vger.kernel.org Cc: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , David Ahern , Simon Horman , Ido Schimmel , linux-kernel@vger.kernel.org Subject: [PATCH net-next v2 6/8] ip_tunnel: add drop reasons to the transmit path Date: Sun, 13 Sep 2026 06:49:35 +0300 Message-ID: <20260913034937.875068-7-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260913034937.875068-1-littlesmilingcloud@gmail.com> References: <20260913034937.875068-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_TNL_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 fa8bd552122f..30378a0d2272 100644 --- a/include/net/dropreason-core.h +++ b/include/net/dropreason-core.h @@ -134,6 +134,7 @@ FN(GRE_INVALID_HDR) \ FN(GRE_CSUM) \ FN(GRE_TUNNEL_NOT_FOUND) \ + FN(TNL_ENCAP) \ FNe(MAX) =20 /** @@ -643,6 +644,12 @@ enum skb_drop_reason { * endpoints and the key the packet carries. */ SKB_DROP_REASON_GRE_TUNNEL_NOT_FOUND, + /** + * @SKB_DROP_REASON_TNL_ENCAP: failed to build the + * encapsulation header of a tunnel, e.g. an unknown or + * unregistered encapsulation type. + */ + SKB_DROP_REASON_TNL_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 0260a97e990e..e7757c0a09be 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -580,6 +580,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; @@ -593,8 +594,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); @@ -613,8 +616,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_TNL_ENCAP; goto tx_error; + } =20 use_cache =3D ip_tunnel_dst_cache_usable(skb, tun_info); if (use_cache) @@ -623,6 +628,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) @@ -632,6 +638,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 @@ -640,6 +647,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 @@ -657,6 +665,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 @@ -671,13 +680,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; @@ -705,9 +715,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 && @@ -728,8 +744,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); @@ -746,8 +764,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 @@ -774,8 +794,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_TNL_ENCAP; goto tx_error; + } =20 if (connected && md) { use_cache =3D ip_tunnel_dst_cache_usable(skb, tun_info); @@ -792,6 +814,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) @@ -805,6 +828,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 @@ -814,6 +838,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 @@ -848,7 +873,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 @@ -864,7 +889,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 Fri Sep 25 12:02:14 2026 Received: from mail-lr2-f12.google.com (mail-lr2-f12.google.com [74.125.230.76]) (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 9957C394470 for ; Sun, 13 Sep 2026 03:50:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.230.76 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789271413; cv=none; b=TgzlmEJ32wFbHY0yFB165b37noD/vcaTGHJkHlkwR80jBNjVR7EueclMAA3HOOOQzvTdncEfGEcoM+Z8RjaLhjRhBnkMf+TDNVtuPIzPtj6aJDcPHUsVD/GrJw2huPShreHqMRnk9/Lj1806zYppYi/ATdzfjuGF5i6Ev9Eo3is= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789271413; c=relaxed/simple; bh=/oG3YIvJhAo6OYWJCL2Pg+8q6vizZcpGDgF6eNKJsAE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YQ8yTy9cOLUpzIZQK/jVnr6aRbePHnXxsRBsnPyQ1k7nowydbAcVIrFssdOX1jomt0gD5uaJjN4XSpvj4NA/+qVIkFf88dycrTNv2D+FUR92OMf2vzLH1fsZn7vLiNGKGYaPp6yExzfIlqmIRBQnOHTMxVvdGOsszsD7liUHRBM= 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=I1S/XLpM; arc=none smtp.client-ip=74.125.230.76 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="I1S/XLpM" Received: by mail-lr2-f12.google.com with SMTP id 38308e7fff4ca-3a2ff148dfdso5636521fa.1 for ; Sat, 12 Sep 2026 20:50:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789271409; x=1789876209; 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=LpAqMHR5ZqpB9HlonWiY5EXSz+WTWjFXdeSofzOPQcc=; b=I1S/XLpMZfkaUlaDkH/wWW2GG1JfHOB6c/KXQ973gaJ1u3pMMgID+OVzCD8E5JJBKp 4j1MZSMm1NJyGbrNQqIUMhuaD2rxS618qVJlKu5TEwoWyfR7ld4r4LNCvkXjdyG/o9/M 60+xlzmmLqgv8dJerSV/3Xydg43aMh4tXkvSL8Fgv1UAdOmsUEE2bnjMbT4Y1RiU7xT/ 7Jc5F8EqrXr15W0jLoFIVozjVBf4qzQTNUjLdkB4wV5K/wA3jf8U+JgIdw7B4moXObNx SC5QA+cLbn4KEnkQNMWZuh6jCuG7oFk+nmRE+izeqwHfuXo23UXC+QDDduStTPtwR6PR WVvA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789271409; x=1789876209; 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=LpAqMHR5ZqpB9HlonWiY5EXSz+WTWjFXdeSofzOPQcc=; b=Nn8MAaqC+FG4OKEs2WWWQoyuRKnzBmsQ6q4ZBR1HyOGNN/T0MRxSDjTb1O+Kd48pm8 //grfhO9y0Quap+8lxAsk6cKbYaabtV8SJ9PDjSfXckXfmWjhWTIP/I3cb+aorUxE3/c QyrrqtmViUyirXRr3kYQd91l+yrXJpZir+iiJX0BZuRowJxUHrqczBe2lUbEineGIa0o 8rjU4SK6rQUaVFvFwulOk5DgslREJzHDzR4ezV4BhnPlrzC5BgjDHysKBqtVd5rMPvWC gXudae/PizbErivQWTeKHfJGcI3t0K+fBDmgpanBMk5+/TpibLoUIFQOEYVkx403tYeV L52A== X-Forwarded-Encrypted: i=1; AKwUvBwSs2+MC8+khtnmZPkiDELylK7I532jPY1KAr8lf7QoYLQIAbfGAaeLS7eZr20HE7bYpP/aTahbwCMxFw0=@vger.kernel.org X-Gm-Message-State: AFuF++k63O9e2S2twKbc/1UWf95gyWyTk1H0DaSg0BWjPwIELUdKFyLR ZsIMUoTE1bdXaqUR1mcFgIIpzCB8KEYBMindCU1ha/lHAxjjXEzpol1o X-Gm-Gg: AYBFou3uSgSalevyvmPE84NumvZjj7TiEtQdbEffLPM/g/p5VUh1GgFHYgXYTPdYEQb JcKASF2GadSQW5jftDcRM2nW/aXYdzQfYJHxEQBeR40nuqp8BPajN9GqgxlgIMnJYt76vS0TjXW eMoqqCZC4uAoi6rfubsWCtvEOBLyL2FE4IKJN7XIeDK0nD86uHqmyvZnxTPQWvcbcYFMyKPXTOj Mr9Rj+XntCDoqQUm7Cto00OlZivhLsHC6ZKIj7Eg4QwAAjebFYmsZ3GkZdk4Y1cKL4tSkYnp7tq bnra/4bKXMK+popbRvtPqzkcic/GHIb8KKqtoQ4zQKf4OTFGRZ153N45GyWhMuL+zSuDR4C/NtQ nbI+qlC5xxpJ4PMbWvsLC4l5JYF8gkCchYX2Agtb7CFlntK1Q5rKgPNu+iNpsxz8P+OuzxCrZDZ QF3tfgzZvivYgyLJ3hJzsMhahpX370y7MjWgFqrjqcqpRDsfYWiWU/PndWgcB5aBoGPBmmuxXrg lThmTzLkn44C1+XJYdlDIilUABeb0qXmdX2beEBEq6S X-Received: by 2002:a2e:a98c:0:b0:3a3:7681:6d69 with SMTP id 38308e7fff4ca-3a5b37efbd0mr5678121fa.18.1789271409296; Sat, 12 Sep 2026 20:50:09 -0700 (PDT) Received: from dau-home-pc.. ([95.139.134.117]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-3a5a332737dsm17277051fa.22.2026.09.12.20.50.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Sep 2026 20:50: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 , Ido Schimmel , linux-kernel@vger.kernel.org Subject: [PATCH net-next v2 7/8] ip_gre: add drop reasons to the transmit path Date: Sun, 13 Sep 2026 06:49:36 +0300 Message-ID: <20260913034937.875068-8-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260913034937.875068-1-littlesmilingcloud@gmail.com> References: <20260913034937.875068-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..7b9687f1de0c 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -507,6 +507,7 @@ static int gre_handle_offloads(struct sk_buff *skb, boo= l csum) static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev, __be16 proto) { + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; struct ip_tunnel *tunnel =3D netdev_priv(dev); IP_TUNNEL_DECLARE_FLAGS(flags) =3D { }; struct ip_tunnel_info *tun_info; @@ -515,19 +516,25 @@ static void gre_fb_xmit(struct sk_buff *skb, struct n= et_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; 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,12 +551,13 @@ static void gre_fb_xmit(struct sk_buff *skb, struct n= et_device *dev, return; =20 err_free_skb: - kfree_skb(skb); + kfree_skb_reason(skb, reason); DEV_STATS_INC(dev, tx_dropped); } =20 static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev) { + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; struct ip_tunnel *tunnel =3D netdev_priv(dev); IP_TUNNEL_DECLARE_FLAGS(flags) =3D { }; struct ip_tunnel_info *tun_info; @@ -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 @@ -660,11 +681,13 @@ static int gre_fill_metadata_dst(struct net_device *d= ev, struct sk_buff *skb) static netdev_tx_t ipgre_xmit(struct sk_buff *skb, struct net_device *dev) { + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; struct ip_tunnel *tunnel =3D netdev_priv(dev); IP_TUNNEL_DECLARE_FLAGS(flags); const struct iphdr *tnl_params; =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; } @@ -714,12 +746,14 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb, static netdev_tx_t erspan_xmit(struct sk_buff *skb, struct net_device *dev) { + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; struct ip_tunnel *tunnel =3D netdev_priv(dev); IP_TUNNEL_DECLARE_FLAGS(flags); 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; } @@ -772,10 +813,12 @@ static netdev_tx_t erspan_xmit(struct sk_buff *skb, static netdev_tx_t gre_tap_xmit(struct sk_buff *skb, struct net_device *dev) { + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; struct ip_tunnel *tunnel =3D netdev_priv(dev); IP_TUNNEL_DECLARE_FLAGS(flags); =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 Fri Sep 25 12:02:14 2026 Received: from mail-lr2-f12.google.com (mail-lr2-f12.google.com [74.125.230.76]) (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 B1D31399001 for ; Sun, 13 Sep 2026 03:50:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.230.76 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789271415; cv=none; b=q+21HXWFfYjX+iArNbfxOc3jpl4CsBYk742ORDTUPDyCbTKXFnLHP0BHNRL/NzHyoHCCAmo6ERaWXkoI10B679s7c5bJsS1H5pFGh36YgTPFYlcCSaMa2nKbg/fp+OTzoNngaa3ReTyyXNsZ4tDdNkGRbbwcDOK3/vglbiACwlA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789271415; c=relaxed/simple; bh=ZKzuOEDOFX7gx1ZtBwNTWWDeAelY+eS5O399Nzpmhps=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Ggx/OQJKVCs7Wmk+1FRfJv5CvGjcv6OSrtBK7BaDOZvBDMUXBOCqkrHFckpdgMKcW+fOD7dLo1TWK9XpIRkrkEJ51B21d1BMDVipmi08GTr92SWfuLYtQBSQB8eEXdbv7aQl+ey0l175NVk7xC/lgyLZbGRq6JBQA7ZUAoRvbVQ= 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=iuWYKgd9; arc=none smtp.client-ip=74.125.230.76 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="iuWYKgd9" Received: by mail-lr2-f12.google.com with SMTP id 38308e7fff4ca-3a59bc470d6so10083231fa.0 for ; Sat, 12 Sep 2026 20:50:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789271410; x=1789876210; 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=l3g8q3TyEM0z+Vg+W2FsBr1zsUMst4iQ9kOdl9YDWuA=; b=iuWYKgd97zuJtCpOmXh/O6uG2l8fMRv1TXcRMQ6eNDb8arXKRtEvNmzkIAA8O1D+kl 07A1uu1R25p/l4ABadqbLrEDOq1LEr08fGzM5GJr+OB93xL2+/yeCMYwqC3j+z1lN9/0 WS1V5jqYMa2bEdicu3wlLhZwZtF1BiGqg2SvpxHQjKr/d3EHaaHckmSjs0PUdSK/HpeV aE10iVRdJ2fr6xfEKygrdbmr4LlDLghWTOQcgbCcSn5hBBItxqM1Dqk/cyf77obmLvAz GcIbMEWbtrP8x0EUlRN6ailJ04WvcjMBwnnO6PIYZKKwlcPji3RNuQjeCGyGjx0swUG1 w3WQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789271410; x=1789876210; 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=l3g8q3TyEM0z+Vg+W2FsBr1zsUMst4iQ9kOdl9YDWuA=; b=Q9/5GvKZOZgqFnsRLxQYs1Y8WTAsBAwCSXwwTjuFA1H7Tzel430sij4w/0GvQ8AUoL UqpiAnS0wJGxkeq2KycSaMYZqUpoK4rKlPt67naHRdcB3/0pK4j1Qajn2id+lCjtZ237 zZ6LT+tMcNrbgnJHOyU2+xPZ/n5Gt2FBWjOhrcBqcf4G6dtFJqXgQW/kAOJvu9jblf0r Ok5EbemfLEOsvcct4rRTXJCpan3F9hbfRr9dYGlGZ/ekA3jGvM/myMDXL5D7AY0QrWpU mYzvafOzVvCjyp4MfPCxL1/2Yban7Al0INHvKvFD3s1dSy6GZ3etWZoD57FhaYLQ4Ofb A19g== X-Forwarded-Encrypted: i=1; AKwUvBx9/S/SK4K4G4SoA6RRzAHSQ9w8Q3GSryVcjbAyJ2OecCWYs046NP+mKa5riv7FnODZY/F7ocvdp81ys/k=@vger.kernel.org X-Gm-Message-State: AFuF++n6PsCN1ygcB5wmbmAZOGEQfX65jFBeLJNR3ndNHKqj56JaJ/kj 9liBKLhC1z5Ode1/Ne94BIyZDc2+pKZBt55eRYurHEc6vhMyQ8JvRzqs X-Gm-Gg: AYBFou05ZS3l/0uDCGKrjEVP3K0URKIrewaqRMT9T7UfoA5jiOrL2NFCCH67tC8MxIR fj17ZYtCagOXEuRXI40jnz/KnO8IIu4t1qf0XeVyL545yvfYoVwW87ijeVfsrCkXiQrMBw7Trtd ZbJPxS/Z1w8HY2VAEEWNntc+ZWF7zXlbKj0B/V1nW4NNF54eTcfcwUk726Wyqg98GJFfKDQyF9W N0jjtgmHbgwIVlTs9nF87iRWV82m+sYyv0B3ERQITIYlDtEuu2vIxtLxW88lgoyPTIkXY+//Hix r+wvzcZD8NzfqqBEIPKw+lmsU/55s4nYkWndhKm7sq0ErrYMDLNw14Xtfbex9twX6d6DHkpTxuX 6Aptqw2vsg889Ug6+nnOWJIUUi5YwVGmc2pMK6iG3gMnnUZcyDlVvzHcKiMJi5Q8gn9AVEn0H4n MsrhPK3FhXgi9ws8wDJdCAyCxtY7lk9ffimVSzc6LzinZdVnp2qdcETmL3fDh29/HdekySxuOnD W7DgJBvfCoCBSMCIJWJd1W+r+EgdTl5wuyitGySOnOm X-Received: by 2002:a2e:bc02:0:b0:39c:624d:82b9 with SMTP id 38308e7fff4ca-3a5a4ff7e62mr30202781fa.4.1789271410359; Sat, 12 Sep 2026 20:50:10 -0700 (PDT) Received: from dau-home-pc.. ([95.139.134.117]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-3a5a332737dsm17277051fa.22.2026.09.12.20.50.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Sep 2026 20:50:09 -0700 (PDT) From: Anton Danilov To: netdev@vger.kernel.org Cc: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , David Ahern , Simon Horman , Ido Schimmel , linux-kernel@vger.kernel.org Subject: [PATCH net-next v2 8/8] ip6_tunnel: add drop reasons to the transmit path Date: Sun, 13 Sep 2026 06:49:37 +0300 Message-ID: <20260913034937.875068-9-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260913034937.875068-1-littlesmilingcloud@gmail.com> References: <20260913034937.875068-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 | 73 +++++++++++++++++------ 3 files changed, 142 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 047c4f57a828..a510be5ad702 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,16 +918,20 @@ 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 ip_tunnel_info *tun_info =3D NULL; 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 if (t->parms.collect_md) tun_info =3D skb_tunnel_info_txcheck(skb); @@ -911,13 +939,13 @@ static netdev_tx_t ip6gre_tunnel_xmit(struct sk_buff = *skb, 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 @@ -930,13 +958,14 @@ static netdev_tx_t ip6gre_tunnel_xmit(struct sk_buff = *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 static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) { + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; struct ip_tunnel_info *tun_info =3D NULL; struct ip6_tnl *t =3D netdev_priv(dev); struct dst_entry *dst =3D skb_dst(skb); @@ -950,18 +979,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 @@ -981,8 +1017,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 @@ -996,8 +1034,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)); @@ -1009,10 +1049,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); @@ -1030,6 +1074,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 { @@ -1040,11 +1085,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)); @@ -1063,6 +1113,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 @@ -1081,7 +1132,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) { @@ -1100,7 +1151,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 458ce328311b..d804c67c4be3 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -1097,6 +1097,7 @@ EXPORT_SYMBOL_GPL(ip6_tnl_xmit_ctl); * @encap_limit: encapsulation limit * @pmtu: Path MTU is stored if packet is too big * @proto: next header value + * @reason: drop reason, only written when the packet is dropped * * Description: * Build new header and do some sanity checks on the packet before sendi= ng @@ -1110,7 +1111,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 +1144,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 +1167,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 +1187,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 +1199,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 +1225,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 +1240,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 +1263,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_TNL_ENCAP; goto tx_err_dst_release; + } } else { if (use_cache && ndst) dst_cache_set_ip6(&t->dst_cache, ndst, &fl6->saddr); @@ -1276,8 +1296,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_TNL_ENCAP; return err; + } =20 if (encap_limit >=3D 0) { init_tel_txopt(&opt, encap_limit); @@ -1306,7 +1328,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 +1342,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 +1353,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 +1393,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 +1435,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 +1458,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 +1468,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 +1482,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 +1505,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