From nobody Thu Sep 24 14:25:20 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 EFDFE43934D for ; Tue, 22 Sep 2026 22:15:19 +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=1790115331; cv=none; b=Y8XT7OND62UJ8JlhLP2It94t7XyFPx1tM7yuS9Ki3z+NnfMxxi7ykLKPTAlmM8k0kkucL7u9cm4v/luZT2FnPdtCf8PNWjwD26pfH67ZvoQpxcJT+1C5IRMqyc18q3qXGEn6kHtKqEPQ6klLw+9fjCo9d3JEH2csfu/AgUkeQSo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790115331; c=relaxed/simple; bh=tTFIjP2lUqDo4uBQnAC7/4MAr+5gOE+O65czI4FkXPU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=t3CUyMRLX3ipQ8Cqjde3scTbjSxfpMnkfHc89t5e/ofHublyT3U0/4/IrxTpD4OZoAL390ljN7vS+cidbg86UWvuJ/eb90sUlUi6Vcd5D28Fy+sKgZwYLBMcicMbMM2jlJiEIUgYMSwL9+8q4m1IU9FnOkAdvIhbwKguNvSD9Zs= 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=RnL+rlg5; 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="RnL+rlg5" Received: by mail-lf2-f12.google.com with SMTP id 2adb3069b0e04-5b5e4f17450so276110e87.0 for ; Tue, 22 Sep 2026 15:15:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1790115316; x=1790720116; 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=kxrxF4xisblpUZV/JRrokwxludzSUbZ0J3lAsXbm1I0=; b=RnL+rlg5nByHOOINTtjiqgEfFvNOHTeWZ9Xe5lRmUk6ASPhycB7gWamQgp0lt30gAL pj/UHyIGn3QOZgQzPR3hGTIj4gCBLlFcvwqadbAA4pVkAg7FAkW9YcQgvs4daC9FB+f5 Q+NY09q0LudgyVlpuR4L+ghv+to8FGyBr7NMBHud9mUjeiz048kC+n1VjCwNBgMCHpoz 6HsYDN0l7oFOEEmTRY8gsCYJGAQ4mt/df/3qNUcVXPv/MONayoPVtWHELJCfH/S1xi2s wiDdu7XoUp2EinzC1DZPADEZnK3+V9Qedw7qr5ha9P7KvA0s6X/IqUXSMiDeJYgNW/Ts yA0A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790115316; x=1790720116; 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=kxrxF4xisblpUZV/JRrokwxludzSUbZ0J3lAsXbm1I0=; b=z/eipWsfnEy+jVBxhTDp5x+H/EJlF2iraWBrxKx+TS53py2RltWGSbFEXZOIDeUzuO qcrNz/jTJIouZ6okwJIgtmnUy1ZFJENniQmuvg6IPvRPosyqBQNGFOj+jU50rCjobD02 LSt2yPlL54FoMK2G/4wnfunSX/lgf1tzpcOWkOY/9EWzAyZhi6795fXOmorzvgL92ZUc qXmQ/zLwDFSQYH8r3qQw7d/yQBVq+NbI22p1lw+WLcygbl7W90YVGQ8LL0uBsa2RIyKs /bWTDMQCtWDmQ3KPHhySQsi75t4ePkF6uxGLY3BwhZIZHgJ1CA1HiLlop2cOGE+FKccq AJ8w== X-Forwarded-Encrypted: i=1; AKwUvBz12f69q+BgKD8poJykJjIYs4q6FtpcPxLlGVr8zbapmaQKT8/7BOSBdtovEAL4qKWhQ4jUZEn77VYxA9I=@vger.kernel.org X-Gm-Message-State: AFuF++kD3NwGXsFFAmAPk2vrUraHqjpKTwLj4c38NIhPAUW0SldQM6ze A+7oD888TnhaFMIRZUVSqsuue4WE4E3jz42/weZB2Wy3DYRKcS80d/+Q X-Gm-Gg: AYBFou0qWllBj6FcFjzi7WI+fuvqmZZLj1io8LQn3hrYcOSqPB4zIc/lzGqCI2BfmMb h7azu9FR3jRwJR04Hu4HX7XwIiAcQmyZ3DlprvA1hCKcrXvPACr22S7KZvbjY5FjHNrGGq48Sg0 0h/1LVHJ2sXyJsBqoEYmgGKzrGbRmKIds9DPlk9/p77KOk6ueb9oqkvHtHT5Y7h5Mrw44W35FaU 90fdUfaI7FWU4KFjVUaR29WbY4T9nHVHYhCLQn3UkJT4hDXsA6AnteGFlYx9YYRBFUw1H0QKO0b DZdFIS/OJrQ4jyX0VZADTs2zS+kWdfii1RBjPL9ACW/ifMSpTSte5RTv4H0MTVRn6lOPxqmQIgd gXyF9/qIoGXTAIJIfnBgl8FbOlascAbQUhR+PaPVf9jvCRUvdJEZeEkZGse5ghujLYGz8btrkDA 4alPAyrAjBO+i8zzdkX8zJvPr0mNq7d+O9wbFzbN8yNs0i+1AEI6b0f690+JrCfy0c4TRqwvEl1 lx4nvz1vbnIjKix8EBsRRrczitPDM9ug+z3rZVUM2M1sP1KXKq6Aia2RmnyGQ== X-Received: by 2002:a05:6512:2241:b0:5b8:99b1:4875 with SMTP id 2adb3069b0e04-5b8d8971e57mr185828e87.28.1790115315639; Tue, 22 Sep 2026 15:15:15 -0700 (PDT) Received: from dau-home-pc.megasoftware.org ([94.28.220.48]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b8d857873asm164920e87.17.2026.09.22.15.15.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Sep 2026 15:15:15 -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 v4 01/10] ip_tunnel: add drop reasons to the generic RX path Date: Wed, 23 Sep 2026 01:14:58 +0300 Message-ID: <20260922221507.3268127-2-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260922221507.3268127-1-littlesmilingcloud@gmail.com> References: <20260922221507.3268127-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 the single kfree_skb() under its drop label: - the tunnel options carried by the packet do not match the tunnel configuration (checksum or sequence number), - the sequence number is older than the expected one, - the inner network header cannot be pulled, - the ECN decapsulation check fails (RFC 6040). drop_monitor and the skb:kfree_skb tracepoint do see these packets, but all four as SKB_DROP_REASON_NOT_SPECIFIED from the same call site, so neither the reason nor the location tells the failures apart. Only the device error counters (rx_crc_errors, rx_fifo_errors, rx_length_errors, rx_frame_errors) hint at the cause, and they are not tied to the dropped packet. Add two drop reasons for the tunnel specific cases and reuse the existing ones for the rest: - SKB_DROP_REASON_TNL_OPT_MISMATCH is used when the packet lacks the checksum or the sequence number option the tunnel is configured for, or carries a checksum the tunnel is not configured for, as the checksum check compares both ways. This is a configuration mismatch between the two endpoints rather than a corrupted checksum: the checksum itself is validated earlier, in gre_parse_header(). - SKB_DROP_REASON_TNL_OLD_SEQ is used when the sequence number is older than the expected one. Unlike the previous one, this is a property of the received traffic: a remote endpoint that restarts and resets its sequence numbering has all of its packets dropped until its sequence numbers catch up with i_seqno. - pskb_inet_may_pull_reason() already computes a drop reason, SKB_DROP_REASON_PKT_TOO_SMALL or SKB_DROP_REASON_NOMEM, which has so far been discarded. - SKB_DROP_REASON_IP_TUNNEL_ECN already exists and documents exactly this check, but until now it was only used by vxlan. The sequence number check is split in two so that the two cases can be told apart. The error counters are left unchanged. ip_tunnel_rcv() is the RX path of ip_gre, ipip and sit, the latter for IPv4 and MPLS payloads only: ipip6_rcv() handles IPv6 in IPv4 on its own. The checksum and the sequence number options only exist for GRE, so the two new reasons are meant for ip_gre. ipip and sit carry neither option and only hit SKB_DROP_REASON_TNL_OPT_MISMATCH if their i_flags are given those bits, for instance through IFLA_IPTUN_FLAGS; such a device then drops every packet that reaches ip_tunnel_rcv(), with or without this patch. The ECN reason applies to all three, while the length ones can only be hit through ip_gre: tunnel4_rcv() has already pulled the inner IPv4 header for ipip and sit, and pskb_inet_may_pull_reason() has nothing to pull for an MPLS payload. Assisted-by: Claude-Code:claude-opus-5 Signed-off-by: Anton Danilov --- include/net/dropreason-core.h | 17 +++++++++++++++++ net/ipv4/ip_tunnel.c | 19 +++++++++++++++---- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/include/net/dropreason-core.h b/include/net/dropreason-core.h index 12f909651591..edbe58a22ddf 100644 --- a/include/net/dropreason-core.h +++ b/include/net/dropreason-core.h @@ -129,6 +129,8 @@ FN(PSP_INPUT) \ FN(PSP_OUTPUT) \ FN(RECURSION_LIMIT) \ + FN(TNL_OPT_MISMATCH) \ + FN(TNL_OLD_SEQ) \ FNe(MAX) =20 /** @@ -612,6 +614,21 @@ enum skb_drop_reason { SKB_DROP_REASON_PSP_OUTPUT, /** @SKB_DROP_REASON_RECURSION_LIMIT: Dead loop on virtual device. */ SKB_DROP_REASON_RECURSION_LIMIT, + /** + * @SKB_DROP_REASON_TNL_OPT_MISMATCH: the tunnel options + * carried by the packet do not match the tunnel configuration, e.g. + * a GRE tunnel configured with 'icsum' or 'iseq' received a packet + * with no checksum or no sequence number, or a GRE tunnel without + * 'icsum' received a packet with a checksum. + */ + SKB_DROP_REASON_TNL_OPT_MISMATCH, + /** + * @SKB_DROP_REASON_TNL_OLD_SEQ: the sequence number carried + * by the packet is older than the one expected by the tunnel, e.g. + * after the remote endpoint restarted and reset its sequence + * numbering. + */ + SKB_DROP_REASON_TNL_OLD_SEQ, /** * @SKB_DROP_REASON_MAX: the maximum of core drop reasons, which * shouldn't be used as a real 'reason' - only for tracing code gen diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index 0875474a578a..c94f4c055027 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -384,6 +384,7 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_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 @@ -398,14 +399,22 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk= _buff *skb, test_bit(IP_TUNNEL_CSUM_BIT, tpi->flags)) { DEV_STATS_INC(tunnel->dev, rx_crc_errors); DEV_STATS_INC(tunnel->dev, rx_errors); + reason =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; @@ -419,7 +428,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; @@ -434,6 +444,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; } } @@ -457,7 +468,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 Thu Sep 24 14:25:20 2026 Received: from mail-lf2-f13.google.com (mail-lf2-f13.google.com [74.125.229.205]) (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 59C4F5293E2 for ; Tue, 22 Sep 2026 22:15:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.229.205 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790115330; cv=none; b=Qaji+GRRVk5cT/T0jx4EnSWUT/h4G32QPewyiVIKiAkN0xXnnoCXmd4+z7OBMjcBBo8aTBp0l2udIiHCIpEMZ1AusivKt/4utb46+87lxOVDbD+9vThqwVc0Wp7Il6O0e4p+msDbjgZZCz4cd8G0e5BaVUDqjpCUC4znWQjfz6I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790115330; c=relaxed/simple; bh=lDaeQywAkd0uBlKk3oiOi1EGJ4dlkQdf6ygCCL5j95k=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kONadbhdemlF2HGZZNtcw9ZV1kixv0q5luvNdxkFwF8c5xj3kGbwjnTQFYDVAaPKf5eKFgtdsuLFK6mg4Jvxwb5EOiz7708k5mpFhCVUT9F/PTOxil73uyalwJt1dW89qddfHzClOBiWXYSHQwsGYHYGKdqe3JC9iTJYSs0vcxM= 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=Ae7udJzt; arc=none smtp.client-ip=74.125.229.205 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="Ae7udJzt" Received: by mail-lf2-f13.google.com with SMTP id 2adb3069b0e04-5b8c3de61a3so243598e87.3 for ; Tue, 22 Sep 2026 15:15:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1790115318; x=1790720118; 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=bP3J1wrqvElmNl+E95+ncUWTRk8fLaOH2UYEkTJtxjc=; b=Ae7udJztTjNsdkZoBV4vPVXSzfwa00JnuqFLc+e5Z3XSLMLmLF+ANGavlC7ANVuTq/ r3cadkB1CIngRLAVaJARp05b/vhT4fd3Tv5uN2DmgXYN2XJTZzsKVVd3sdEm3hJx0Thb n6UzaEUDQ/LhlKdT/SZ2s5LwSCtkY+LFjC/IVPK1Jdvm6nNwfUKivYGi/avtIYLFKktG KsZQ7l4ZLqjLEcp0GDUQ893Hl5C9MSTBsxl5vTtyCuusKxTbfPdu1765u2yIjUuiMKfH kZbhG7HjTO42qbOzJZI1pd0IcsO/DztpslE2/WGOD+7QN7WVKRMmGLh0Nrzb45/0fh46 CFZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790115318; x=1790720118; 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=bP3J1wrqvElmNl+E95+ncUWTRk8fLaOH2UYEkTJtxjc=; b=ldUx63Ejph5ymI6upU0T59xbn1+vZhiAPeC/M2VkyP0YygAEo7bxuymK7xrMRLZY2Q yRWwCSgLoEqtc9VfV7tyTusgo+eyDu6o0GOwxFdIWwVRFhJYMjZcgdSEQbjE0YrCe3EQ 8xk0SaIsMQ9FWuiZUnOZw9AHt70mZVulahnWelREY4859CbK4902GlSf/MJkNAt6DO7T lD1yqCAbIBfM3p320ZvcvKUDYIqwbV/hwLgCcCnSxW+jS6H/alwB9oE9Iy0cqoYvL1NR 2Vr/2s/jKzjZis8jYInJS9nHeVDst91Jq+1mbZImD8M9/5N4hdGCB+/d8I66IQ04SWRp wLaQ== X-Forwarded-Encrypted: i=1; AKwUvByhZgCyhGsxYkBkF0CC+5KueDxaq4yypiyOpTj3ZzTb6UwSXxWzVQLpDtCKhVJd08bgqQ67Tfr4fZrBKZ8=@vger.kernel.org X-Gm-Message-State: AFuF++mlmQ78N5Kz+JBEg+1qaULCjiKf2OdHT5lCXnvoQtGVmUGsUixZ Jjxu7xyugczN/yZH6Q+RKjV6AGPxFlWvPyyoo54kown2TmDrctUUpdM8 X-Gm-Gg: AYBFou2Spl+RRzZKxO9X4EI8I+QILkdqbhYi4XLE1YByKUUfKqRQxisjw89/gI7e7Fe 5QTtF6Jd9RUBFqEGcX1s8VTMJmGWK/P8Lg4iCANMAC4ElHMbLI9+e8rPHp5nnkfe7BOEwMX6OJ+ q36e6mvkeHMtjvmbQvuSjDv/4iKKBTY16nIG22vT0NmsiGgvTagSaOaN0o8W+sQnYU/qOxNIvjz XPMvXP5a/4aqtvs0S0wDviQUHh/7zv4VVqdP6MKtgoKkSJKn0TRWxS7L5PCtXaUIvnGpmic5K9B 1I/nvkv0WDxpQmnlC4ETA3CK0F5pnfqmHvD2yfb1YvsYXG0wtXzX1vpFhRJYx2nCr0NkwhoJ5v0 zVEuzPv6pwT9+fgLE8VwrpaPS+oZPfJAvGqAvHehw1sWQoWiXO+2fhFt+yosIJ4fNlZv7DCJd5W qpdYWDCRm5XMleEicP1CbcYDgxCQLN//vmBlIPeOKBbQo7ePB0zrxxyjXUlRgwAh1iDfDKDkRKN J7CXxkWTdcJx6lMqR6vrlrFlK59AddZYmUpFbv4sUqF7s7GBO2h/msQUmQtLFkGx929ASrX X-Received: by 2002:a05:6512:318c:b0:5b4:fdbe:ab4e with SMTP id 2adb3069b0e04-5b8d895e710mr201829e87.25.1790115317953; Tue, 22 Sep 2026 15:15:17 -0700 (PDT) Received: from dau-home-pc.megasoftware.org ([94.28.220.48]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b8d857873asm164920e87.17.2026.09.22.15.15.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Sep 2026 15:15:17 -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 v4 02/10] ip6_tunnel: add drop reasons to the generic RX path Date: Wed, 23 Sep 2026 01:14:59 +0300 Message-ID: <20260922221507.3268127-3-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260922221507.3268127-1-littlesmilingcloud@gmail.com> References: <20260922221507.3268127-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: all of its failures share a single plain kfree_skb(). Reuse the drop reasons that ip_tunnel_rcv() now reports and the ones the length helpers already return. Note that skb_vlan_inet_prepare() returns an enum skb_drop_reason that has so far been discarded, and that the ETH_HLEN check gets one by calling pskb_may_pull_reason() instead of pskb_may_pull(). __ip6_tnl_rcv() is reached two ways: ip6_gre (ip6gre, ip6gretap, ip6erspan) goes through the exported ip6_tnl_rcv(), while the ip6_tunnel encapsulations (ip4ip6, ip6ip6, mplsip6) reach it from ipxip6_rcv(). Only ip6_gre sets the checksum and sequence number bits: tpi_v4, tpi_v6 and tpi_mpls carry nothing but .proto, and unlike ipip and sit, ip6_tunnel stores IFLA_IPTUN_FLAGS in parms.flags, not in parms.i_flags. So the option mismatch and the old sequence reasons are reachable through ip6_gre alone. 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 Thu Sep 24 14:25:20 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 37CE0544D5C for ; Tue, 22 Sep 2026 22:15:25 +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=1790115334; cv=none; b=VeoyODTDivsxhLREfwIyANKJsdxWYACbOc9QrqQfA1ZwsDFKUGc7h1naiScpZxMcUT50BFyw/EgYQUGJPyUDze/G1Bk1ybLCy1Toe59Ifdh+vZ+AAW+8sPbHwClo+CQ3eQlUyB3jOdjz2aANLiApYuZs5u3o2DH2leKIgAEaVRw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790115334; c=relaxed/simple; bh=JxSk/JP7u4KcR/HLX+vqea16/v4KdwxvKwkPMvzejhw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Jsw+E091Z1pc2YQMFDibGosP0AiuVBPtIyI1heFvjnVdtVYyUY6DkX1I0B3/ws3KZZwTIp5WCOtroRo5JDR1RA/kuGNYvbdGDSVxY8tiI6ji2dFUA+gQyaGDdQ/BDahpLPBineOYjfAoqc2e2OFVQBV5VPDXvDXI8+ECIbxOlC0= 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=GBnrgjKa; 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="GBnrgjKa" Received: by mail-lf2-f12.google.com with SMTP id 2adb3069b0e04-5b5e4f13d7aso375977e87.1 for ; Tue, 22 Sep 2026 15:15:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1790115322; x=1790720122; 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=IWc4v88VrqhMj8Mk9GQAEuE7z6ifNAFZMAXLHyiJrME=; b=GBnrgjKa496TiwiFX/5+/n3aRIDBp+HGtuutu38bNNxr5SltPLMbzM1gQktXmsljW1 ICCuSuV552ApZZr0JYZfzWCB8H7ex36kExUR4B7sNASSgdNVpDCCSyLqC2qTueJvTnxa krSYxn7vRew8xIk24FQhTI+bvCIAcX+5KN/2XUtM9KBMwxizK3MUwANECXUcalLtD2nI NY+eA9POooqY/Rav32/fIvia6RNY2bG+3EUOW7CvJvNIOumOdOHurk+yrQzdIoCaozsg w4NxcRQINAufLAM1hC2PZgU08jnKCTEUxfealur/5DkPrNDp9VvZAGN1Iw/3tg08WfrA GWUg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790115322; x=1790720122; 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=IWc4v88VrqhMj8Mk9GQAEuE7z6ifNAFZMAXLHyiJrME=; b=n3SBf84blU3cKLAEUZqwndCHO1WBSJwUhl3UD5nuAbaFM99ojafS5ekUHiYuyFuoUr 80Bj1mineIWZ5EFfhkjQJpKv3XZRFaaleRDfJvxU17wRQdepTsO1vgK71bvlXPlwJ3Q0 l0TePWIr30ABpjMowW4fkhmHnd41HkCTiFaGQPhVGVEg+yfvbzyvTjYgLOdN0xdnlh1n y8DS+Ox0aeCzW1aC08Oal4xO2DU1NjhDcLzcBdebgiL7lLzWOIOqvlpFLfkwAGbndNUf jXHyXdL5u1pF2UlGzSc90x5GM1IrU6mKn+GIPevqV1ffY9+IOqjW19/RwC0ekf31T5Vk m5JQ== X-Forwarded-Encrypted: i=1; AKwUvBz8bpwA/R85MqkD+7Q9pu5oZDRt3arxad1oAZq+r1wX6jX8tFVYHtLNUMlliX5MpBjZk7L+iYZhfSlVR5o=@vger.kernel.org X-Gm-Message-State: AFuF++kjxcpIR2VGfM+mbgQ3soeggdWLZ4c3wlJHbOveV0QyIO33aP4L uskPd6sox80SEhXfsLBP6jigEUEg4ltqF+TpCnqACLqPRhZZi6z0k+XR X-Gm-Gg: AYBFou2FFu2kL+8dV/hC9RiFEFX1zHOdt1bXYU2Lm+29zwfJJ0YWXlTr9PKSTr+YLGc 1e/mzq/gZeNgOrakS2pQRRr1/RhwhXuaNtjp8uTUK30L9T7HkTNcsS+aVazvT2lyjjW5ls9EK6y EH6J1wTaZJjVMc/OerZk5hyp1lg8OgsGKE5yMhiZYDYGPgVbWHg91qPEXAaD2IM2GWaurHQsUin fLNbdz2kjssuq3ymLepOcV4vbWxorETcI5Rw01VstK9HmpYuYRNgmCs1Tm+78lP6bnqFBHN0f9B qlG9tDxKx+X6cQ5HCDhCDsoPe6J//DVJLt3zudQY+vXK3i2gePR+c6BeeDMJmFU5GETgOSP7F1f bt9NL5W4eIF/nkQ69GiADsq2vQEfD1G2yAbLechYJGCLr8FUk2tEL7zE+/UCSwtfe4UCZsqlK8Z 1cDJGHHPrZRNTCFoZPHnLQL6EzGPClTlY7/HXM4zte1zKfz8jrj+Kq6UH7grj40ok0FTCJCL3Kr /R0gEKXNr+ibUhMX8PwRaoAWJ0zDn+L6cWuIOhunprz7y1ZmGRqjnnf3q+v0kUqxds2MIhQ X-Received: by 2002:a05:6512:1290:b0:5b8:c226:fe21 with SMTP id 2adb3069b0e04-5b8d89c15a4mr185478e87.56.1790115321565; Tue, 22 Sep 2026 15:15:21 -0700 (PDT) Received: from dau-home-pc.megasoftware.org ([94.28.220.48]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b8d857873asm164920e87.17.2026.09.22.15.15.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Sep 2026 15:15:19 -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 v4 03/10] gre: make gre_parse_header() report a drop reason Date: Wed, 23 Sep 2026 01:15:00 +0300 Message-ID: <20260922221507.3268127-4-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260922221507.3268127-1-littlesmilingcloud@gmail.com> References: <20260922221507.3268127-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 every failure and its receive 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. Make gre_parse_header() return the drop reason instead, with SKB_NOT_DROPPED_YET for a valid header, and let the two receive paths report it. The header length it used to return is already stored in tpi->hdr_len, so the callers take it from there. 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, like 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. csum_err had a second use: the ICMP error handlers pass NULL for it, so that a checksum failure does not reject the header and the rest of it is still parsed, as they only get a part of the original packet. That came with commit b0350d51f001 ("ip_gre: fix parsing gre header in ipgre_err") and becomes an explicit icmp_err argument. The checksum is still computed either way. Tunnel lookup failures still report SKB_DROP_REASON_NOT_SPECIFIED here, which gre_rcv() sets again once the header is parsed; 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 | 5 +++-- net/ipv4/gre_demux.c | 42 ++++++++++++++++++++++------------- net/ipv4/ip_gre.c | 18 +++++++-------- net/ipv6/ip6_gre.c | 18 +++++++-------- 5 files changed, 56 insertions(+), 36 deletions(-) diff --git a/include/net/dropreason-core.h b/include/net/dropreason-core.h index edbe58a22ddf..ffa11206b6ca 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 /** @@ -629,6 +631,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..4cb19abea90d 100644 --- a/include/net/gre.h +++ b/include/net/gre.h @@ -32,8 +32,9 @@ struct gre_protocol { 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 +gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi, + bool icmp_err, __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..e117056525f0 100644 --- a/net/ipv4/gre_demux.c +++ b/net/ipv4/gre_demux.c @@ -56,28 +56,35 @@ int gre_del_protocol(const struct gre_protocol *proto, = u8 version) } EXPORT_SYMBOL_GPL(gre_del_protocol); =20 -/* Fills in tpi and returns header length to be pulled. +/* Fills in tpi, including the header length to be pulled in tpi->hdr_len, + * and returns SKB_NOT_DROPPED_YET, or the reason to drop the packet if the + * header is rejected. * Note that caller must use pskb_may_pull() before pulling GRE header. + * + * @icmp_err is set by the ICMP error handlers, which only get a part of + * the original packet: a checksum failure does not reject the header then, + * the checksum is still computed and the rest of the header is parsed. */ -int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi, - bool *csum_err, __be16 proto, int nhs) +enum skb_drop_reason +gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi, + bool icmp_err, __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)))) - return -EINVAL; + return SKB_DROP_REASON_HDR_TRUNC; =20 greh =3D (struct gre_base_hdr *)(skb->data + nhs); if (unlikely(greh->flags & (GRE_VERSION | GRE_ROUTING))) - return -EINVAL; + return SKB_DROP_REASON_GRE_INVALID_HDR; =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)) - return -EINVAL; + return SKB_DROP_REASON_HDR_TRUNC; =20 greh =3D (struct gre_base_hdr *)(skb->data + nhs); tpi->proto =3D greh->protocol; @@ -87,9 +94,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; - return -EINVAL; + } else if (!icmp_err) { + return SKB_DROP_REASON_GRE_CSUM; } =20 options++; @@ -117,7 +123,7 @@ int gre_parse_header(struct sk_buff *skb, struct tnl_pt= k_info *tpi, val =3D skb_header_pointer(skb, nhs + hdr_len, sizeof(_val), &_val); if (!val) - return -EINVAL; + return SKB_DROP_REASON_HDR_TRUNC; tpi->proto =3D proto; if ((*val & 0xF0) !=3D 0x40) hdr_len +=3D 4; @@ -133,28 +139,32 @@ int gre_parse_header(struct sk_buff *skb, struct tnl_= ptk_info *tpi, struct erspan_base_hdr *ershdr; =20 if (!pskb_may_pull(skb, nhs + hdr_len + sizeof(*ershdr))) - return -EINVAL; + return SKB_DROP_REASON_HDR_TRUNC; =20 ershdr =3D (struct erspan_base_hdr *)(skb->data + nhs + hdr_len); tpi->key =3D cpu_to_be32(get_session_id(ershdr)); } =20 - return hdr_len; + return SKB_NOT_DROPPED_YET; } 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 +177,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 5e877018e006..ae50fd0f6792 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -237,8 +237,8 @@ static void gre_err(struct sk_buff *skb, u32 info) const int code =3D icmp_hdr(skb)->code; struct tnl_ptk_info tpi; =20 - if (gre_parse_header(skb, &tpi, NULL, htons(ETH_P_IP), - iph->ihl * 4) < 0) + if (gre_parse_header(skb, &tpi, true, htons(ETH_P_IP), + iph->ihl * 4)) return; =20 if (type =3D=3D ICMP_DEST_UNREACH && code =3D=3D ICMP_FRAG_NEEDED) { @@ -439,9 +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 if (ipv4_is_multicast(ip_hdr(skb)->daddr)) { @@ -451,25 +450,26 @@ 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); - if (hdr_len < 0) + reason =3D gre_parse_header(skb, &tpi, false, htons(ETH_P_IP), 0); + if (reason) goto drop; + reason =3D SKB_DROP_REASON_NOT_SPECIFIED; =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, tpi.hdr_len) =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, tpi.hdr_len) =3D=3D PACKET_RCVD) return 0; =20 out: 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 c851af22b9fe..d36949cbe9fa 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -389,8 +389,8 @@ static int ip6gre_err(struct sk_buff *skb, struct inet6= _skb_parm *opt, struct tnl_ptk_info tpi; struct ip6_tnl *t; =20 - if (gre_parse_header(skb, &tpi, NULL, htons(ETH_P_IPV6), - offset) < 0) + if (gre_parse_header(skb, &tpi, true, htons(ETH_P_IPV6), + offset)) return -EINVAL; =20 ipv6h =3D (const struct ipv6hdr *)skb->data; @@ -566,20 +566,20 @@ 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); - if (hdr_len < 0) + reason =3D gre_parse_header(skb, &tpi, false, htons(ETH_P_IPV6), 0); + if (reason) goto drop; + reason =3D SKB_DROP_REASON_NOT_SPECIFIED; =20 - if (iptunnel_pull_header(skb, hdr_len, tpi.proto, false)) + if (iptunnel_pull_header(skb, tpi.hdr_len, tpi.proto, false)) 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, tpi.hdr_len) =3D=3D PACKET_RCVD) return 0; goto out; } @@ -591,7 +591,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 Thu Sep 24 14:25:20 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 6EA1F518138 for ; Tue, 22 Sep 2026 22:15:28 +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=1790115343; cv=none; b=j+YvmEI+Z1kHFv4wZN2Av0R8CJchvbUB6NFL4Y/H4PJny7K4dfm/6uoLVS76XmiaZVJxnc2yjd3ErKxDVC/uy1wUbtwIBiY7HhFAvgRm1lNZEaCHymGTChqCZJXyQPzSN7rhroEb4dfUnArcju60zbbCMPt/R/gTP+E1IOHhUqU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790115343; c=relaxed/simple; bh=VRZNWx4ugJkuvukyHgB8smW2wlSxu5AiMHqtTnuMIyc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lJB4xjTc2A3Fe4J6g9tRi/YpsLZjMr/Gz5Utm4aHckkA3MbhUqWxAlS6C4OtH6bP7Bqa4P5rRYe/YuUgOgataXEUAf2WNm2vdfSUDW0RQnHr26A9gPxWIvnxS8q+Xj+aAfF/ZX1LunPgHBMhVcN7VtrK0CQtWWKIBCSMJ8Z3IH8= 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=OFRnd56T; 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="OFRnd56T" Received: by mail-lf2-f12.google.com with SMTP id 2adb3069b0e04-5b5e4f15b78so222983e87.2 for ; Tue, 22 Sep 2026 15:15:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1790115325; x=1790720125; 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=I/01E19apDogLQJb8/WrRagKxzGtq0BoJnfIbRYZXRU=; b=OFRnd56Tmbpy1zWuNVMh105PqknKaj4LtsfoaXlN1/CPkKYFpmtH1kPPdLiTNtuHWo wsU6lq/yZ75LakVFx6db6sovPkW5qNoBhncO6xpeJlbNLuCiUD0GR0/IDMbnkBssYFfu FNZXqRtONaKcfDDO7qlEXOSevMr/Fex2Wus7+8SYR6hKD5adtAslGDcdHGUCKzpQiBLQ mWVIPA0dOIH3ZSorXQNJr+F1BgxP3jSx20ed8TOEoA24j1OLAqIei2zBtJitO5qRZZ9z /8ElRdoDJ1qRrx/+68nhpQ+LBOLOOiirbf8eATufRDalhDqg+2FjlZn0Jv2kQa9xrIBp LF9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790115325; x=1790720125; 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=I/01E19apDogLQJb8/WrRagKxzGtq0BoJnfIbRYZXRU=; b=rH0fyXxbGKKQo5DiqFRol58MgHr7l0WEF0qPTeDbSleqbkjSsUB7O559w5/qsFhYcH iVVljFUg9eGs0LahmduzssVB8MyJWlbs3P4kvLq6nocnhMv5DWNMfc16NQP49zpdIumt /2oeFc2IE3xFj2p17IH7AB5kVixRXJvDr/PkGdqiK/NH6tAAJ7hjbg41sX25P7y8zRbQ hRZp8h/FxZHErAgxE/8ExHURURfH8bb5MM9b7sYEXh027vbyt2a5wXmcUF/8yS022vSy CrjyFSA9Ily9K2LA5vIV4gTj2SoHbXU2JQFHK7/1hEecexlIlADIMf3QqASPwwt6b40z lZ9w== X-Forwarded-Encrypted: i=1; AKwUvBxIYqrNI7AXaDXGtspt0YHt0GR6teT4fKIfE3Y51mX8kkhOZi/dwWPu5NgVhA49p9r6qivurP1R/4wwSf4=@vger.kernel.org X-Gm-Message-State: AFuF++nWYQ21OHadBkRgLLYY2CBecavRWQoKkoY9Q0v3Ywg0MD6FD53q VAc328HTjmFuRMK3HzROYG2ReVSda2m809VpCJIdP0NuHoG8j51HAkSt X-Gm-Gg: AYBFou2Nfv4cg7hyBWDl38GqSWHDrLZoKQ9CP32v2t8kuoWv0dpxA0yy2iutqnTSxlu 6hmLzBL64kOB2WkTEFyhLe3AOD3sxClLudjuO8XMyyDtw17ge2SnLhMghDDrWjJIQQ2TtQoQWax +dOL2hDbtaPKbFbyGhJ57fc7JFqSsiPE3vcRBdTV3pSkMA9ehiH4eyhLmNQYUiM0dSQKE+WaSfs toNXksMaML9Asz3gxrbDtmHaJ4LKeZWnceZ0yezXv0btbHl1zjojqrcAFnwdfma5IPalGerfUct LUF6xhXoQmFiUafGiRwpCR6ALScaMpOjiQtBxiiYolAcUtm1zNSWTUwbT4Jl8Oyzn6fC90/UyWU CU6pZhDIE9NCefcCo3k9rs9MCjBhSfB6tQ/W1WkiMK3I9/IYHcLozrF76bNQnFR7tcYrzB33uZ/ Cd9UE30gXilrguHzXyFDBEj2y2I3gY8MfabvyE90brOb5z+BPrTon1s4A/W/Ucc7capQL/QEHjR wKvjDjFU2PXwPOhZ2oGESw3d7cOTV6Lx4dEyVF+fdDnY6+k7XysccQpVRM8570NRUZHAosf X-Received: by 2002:a05:6512:3b86:b0:5b8:bc5e:b56e with SMTP id 2adb3069b0e04-5b8d89b04f9mr179380e87.38.1790115325212; Tue, 22 Sep 2026 15:15:25 -0700 (PDT) Received: from dau-home-pc.megasoftware.org ([94.28.220.48]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b8d857873asm164920e87.17.2026.09.22.15.15.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Sep 2026 15:15:23 -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 v4 04/10] ip_tunnel: add __iptunnel_pull_header_reason() Date: Wed, 23 Sep 2026 01:15:01 +0300 Message-ID: <20260922221507.3268127-5-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260922221507.3268127-1-littlesmilingcloud@gmail.com> References: <20260922221507.3268127-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" __iptunnel_pull_header() returns -ENOMEM whenever it fails. It can fail in two pskb_may_pull() calls, one for the tunnel header and one for the inner Ethernet header of ETH_P_TEB, and in the skb_unclone() done for GSO packets. pskb_may_pull() fails when the packet is shorter than the requested length as well as when pulling from the frags cannot allocate, so a truncated packet and an allocation failure look the same to the callers. The ones that report a drop reason can only pick SKB_DROP_REASON_NOMEM, as vxlan_rcv() does, and so would the GRE receive paths converted by the following patches. In ip6_gre, gre_rcv() calls the helper before the tunnel lookup, so a packet from any sender whose ETH_P_TEB inner Ethernet header or WCCPv2 extra word is cut short would be reported as an out of memory condition. Add __iptunnel_pull_header_reason(), which returns the reason pskb_may_pull_reason() already computes, SKB_DROP_REASON_NOMEM when skb_unclone() fails, and SKB_NOT_DROPPED_YET on success. Turn __iptunnel_pull_header() into a static inline wrapper that keeps returning -ENOMEM on any failure, so its existing callers are left unchanged; the export moves to the new function. Assisted-by: Claude-Code:claude-opus-5 Signed-off-by: Anton Danilov --- include/net/ip_tunnels.h | 13 +++++++++++-- net/ipv4/ip_tunnel_core.c | 24 ++++++++++++++++-------- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h index 7102aa11fae2..c68031d01c39 100644 --- a/include/net/ip_tunnels.h +++ b/include/net/ip_tunnels.h @@ -614,8 +614,17 @@ static inline u8 ip_tunnel_ecn_encap(u8 tos, const str= uct iphdr *iph, return INET_ECN_encapsulate(tos, inner); } =20 -int __iptunnel_pull_header(struct sk_buff *skb, int hdr_len, - __be16 inner_proto, bool raw_proto, bool xnet); +enum skb_drop_reason +__iptunnel_pull_header_reason(struct sk_buff *skb, int hdr_len, + __be16 inner_proto, bool raw_proto, bool xnet); + +static inline int __iptunnel_pull_header(struct sk_buff *skb, int hdr_len, + __be16 inner_proto, bool raw_proto, + bool xnet) +{ + return __iptunnel_pull_header_reason(skb, hdr_len, inner_proto, + raw_proto, xnet) ? -ENOMEM : 0; +} =20 static inline int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto, bool xnet) diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c index bab42b9e277f..51f1537ce6c1 100644 --- a/net/ipv4/ip_tunnel_core.c +++ b/net/ipv4/ip_tunnel_core.c @@ -106,19 +106,24 @@ void iptunnel_xmit(struct sock *sk, struct rtable *rt= , struct sk_buff *skb, } EXPORT_SYMBOL_GPL(iptunnel_xmit); =20 -int __iptunnel_pull_header(struct sk_buff *skb, int hdr_len, - __be16 inner_proto, bool raw_proto, bool xnet) +enum skb_drop_reason +__iptunnel_pull_header_reason(struct sk_buff *skb, int hdr_len, + __be16 inner_proto, bool raw_proto, bool xnet) { - if (unlikely(!pskb_may_pull(skb, hdr_len))) - return -ENOMEM; + enum skb_drop_reason reason; + + reason =3D pskb_may_pull_reason(skb, hdr_len); + if (unlikely(reason)) + return reason; =20 skb_pull_rcsum(skb, hdr_len); =20 if (!raw_proto && inner_proto =3D=3D htons(ETH_P_TEB)) { struct ethhdr *eh; =20 - if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) - return -ENOMEM; + reason =3D pskb_may_pull_reason(skb, ETH_HLEN); + if (unlikely(reason)) + return reason; =20 eh =3D (struct ethhdr *)skb->data; if (likely(eth_proto_is_802_3(eh->h_proto))) @@ -135,9 +140,12 @@ int __iptunnel_pull_header(struct sk_buff *skb, int hd= r_len, skb_set_queue_mapping(skb, 0); skb_scrub_packet(skb, xnet); =20 - return iptunnel_pull_offloads(skb); + if (unlikely(iptunnel_pull_offloads(skb))) + return SKB_DROP_REASON_NOMEM; + + return SKB_NOT_DROPPED_YET; } -EXPORT_SYMBOL_GPL(__iptunnel_pull_header); +EXPORT_SYMBOL_GPL(__iptunnel_pull_header_reason); =20 struct metadata_dst *iptunnel_metadata_reply(struct metadata_dst *md, gfp_t flags) --=20 2.47.3 From nobody Thu Sep 24 14:25:20 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 C18255275B0 for ; Tue, 22 Sep 2026 22:15:32 +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=1790115342; cv=none; b=GJO0EzXQ7ZScSex1Yj+ZwTs9Ur01+5QGNL9sr+rdQi041RisybFw38SEc8u7ra9m7s5k8fHIkGwdhU/cKPrMW2p/Dy3cI+oh1r22icz3Fap8xwznoCYzT+wSIAtf6pvENth0T0a3SKSRhyhCoAo7nqi6BI1BD/GwbE0yguQ0IzU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790115342; c=relaxed/simple; bh=0D8CTYmDCMH6i7rohPrLX9uQUUqlJjGhNFP9nt80Dvg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=L4ezuScor0Vw9LSN6gZyfAbmTG0GsxQvGpbGBaP2ChfRNGlQtu6BTYXh1YMTZ9pw213Vcplxwz9DazZEov274vsf5r/hMNFZ8K/LO0sKWznqVHT+l9HNuqG5EnmxOeYIa/3xJ7CdAPRmXwaeZvDi23wGqaMoCcAQco6Gs3xok8A= 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=o0PtSNEC; 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="o0PtSNEC" Received: by mail-lf2-f12.google.com with SMTP id 2adb3069b0e04-5b5e4f15cfdso214927e87.3 for ; Tue, 22 Sep 2026 15:15:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1790115328; x=1790720128; 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=vugC9m47cNYpmmwFdzF5Qy5U2YniLLjKVsm9PIdJu5Q=; b=o0PtSNECmp+usg3CpaFaSv+QzQsFAax656m/nG52apHNWN+eB5QFaYJfVc8KVekgBe oZDeAFMj8xiZ/EvS45pNwmw/9yI2Tgxb4eFkuDepF22OInxQg0ln/fi75Q0mitUdECyu Nbat3O4eH/JtgTfQrkn/seOCwz5cHaHjLWdFZa4MA5jcHQeqg6ijFaInu6KzR3ywBCjI 9SX9zV/5pI1xQxizKvcMdAiwd1vY9js0mauUa9qkDJ3mbJI6dWFQSiDnXWa33bL1BhuG tf19HXvwgW56TBw2sUuLI+b0T+4tpABap79p3dILqfHbMattauPZZhOCxNR9juMwXYlC Vo9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790115328; x=1790720128; 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=vugC9m47cNYpmmwFdzF5Qy5U2YniLLjKVsm9PIdJu5Q=; b=sRLCUONomIoPD2D6Yby8w8BZ50FtHDs2Y2tz6W4CzDwlxl0qKfloYPlCjK1lWmYnJT VTB+UwSQlcoQwu90ctekG3jFG1g5E1OMsbbiZmGQhOgt8fx/btDubi9v91JPtRoUGlnc klOldktvwGJ20RKqwNJM7TPt4bJ2+P2+8fY3lAy81xtC15ixws7Rgs4VnKE9AK9uf7ck CJgd6+n8BxyvRXobY6x5mCgnoGrgWN2dS+1J0888j3UuXrSMtBEIuPKDQe4NgQY8QtwN eqp/0iWVY+K7OdiR5KXpie8bBaNAHT6H/f1FYLi+dTTlAXL+fYr8MgoJBB4nYjATBKtw cO/Q== X-Forwarded-Encrypted: i=1; AKwUvBzPfeqaEaWF9WDJ1Uhs4ZKukgxeqZXlUbDU9baHeR6a+U5FV1Np/VIwcQxX5HcRJZKjWgz97BdHFAMwfII=@vger.kernel.org X-Gm-Message-State: AFuF++nFN79ctuf+QChj0EHXgawjsI/tuyngNegJLkhyq8+tiAJ7QRx4 W37bSqmN4QG3xgAfI6F5Iczk40YeU0RL0kmYTLmxkne5O452pVJweFnu X-Gm-Gg: AYBFou2LRyOx4R/cLilbZEyEoZ6+CmrSF9oJjJb6w2kL3KzKP7aVZcOya542Fter/Bs ItinvywZCjaz4G5OSdiZy+vreBjYn2A0BXu1xzXBtqo02cRRmmANhjFovPZwNN6x82xfJ7akwi6 eBzXOlGyMn5B2rUSCHNBQRw5wbZlxPLBSkaV27UWOwQY4yNrBDpuh14Sfb+vXyBLQmoc8PtA7ob Z5yIzbAMzYNMQPeGFN9LX5U9W0/pwy0H10mcWlSy2HnhtYQ0fBcZI0SlsKPQFmABFGG8nOBBgJK PIt+A5ledxDtXuL5+5Yi/fggsAt1W4j6ZHHquZ3s6weW1ygjdaWcuDtVuC0JkmURuMJD5zmfUQJ zcM3mVa64cSEB0qtB69NCCbe+ueNzTJdomQAHbg8O4sAoer95b2wmBZ26fqKqZzYcdVSM6IySzj k+/jovxCdzC43jxMyvWJ9MEkE7gb2eb6AU66rVtg444OVaRQs1KBa1BDlE8vo+tRjQ168yz4uHf EmFdrA80LvfGCU9hgjPzQVyNv9dFXeaoXL+R0/b8MCp/gVWHG4PnsZP4Ia/Aw== X-Received: by 2002:a05:6512:65c9:20b0:5b8:b3a6:719a with SMTP id 2adb3069b0e04-5b8d8987155mr127380e87.30.1790115327614; Tue, 22 Sep 2026 15:15:27 -0700 (PDT) Received: from dau-home-pc.megasoftware.org ([94.28.220.48]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b8d857873asm164920e87.17.2026.09.22.15.15.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Sep 2026 15:15:25 -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 v4 05/10] ip_gre: add drop reasons to the RX path Date: Wed, 23 Sep 2026 01:15:02 +0300 Message-ID: <20260922221507.3268127-6-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260922221507.3268127-1-littlesmilingcloud@gmail.com> References: <20260922221507.3268127-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, as SKB_DROP_REASON_NOT_SPECIFIED from the same kfree_skb_reason() call as a truncated ERSPAN header or a failed metadata allocation. This is the GRE counterpart of a UDP packet hitting no socket, yet neither the reason nor the call site tells it apart. The fallback devices such as gre0 only take such a packet while they are up, and they are created down. Add SKB_DROP_REASON_GRE_TUNNEL_NOT_FOUND for it, in the spirit of the existing SKB_DROP_REASON_VXLAN_VNI_NOT_FOUND. erspan_rcv(), __ipgre_rcv() and ipgre_rcv() now return SKB_NOT_DROPPED_YET where they returned PACKET_RCVD, including the paths that free the packet themselves, and a drop reason where they returned PACKET_REJECT or PACKET_NEXT. __ipgre_rcv() only returned PACKET_NEXT when no tunnel matched, so the retry ipgre_rcv() does for ETH_P_TEB is now taken on SKB_DROP_REASON_GRE_TUNNEL_NOT_FOUND. The length checks reuse SKB_DROP_REASON_HDR_TRUNC. The headers are pulled with __iptunnel_pull_header_reason(), added by the previous patch, which reports a packet too short to pull as SKB_DROP_REASON_PKT_TOO_SMALL and an allocation failure as SKB_DROP_REASON_NOMEM. The metadata allocation failures reuse SKB_DROP_REASON_NOMEM as well. SKB_DROP_REASON_GRE_TUNNEL_NOT_FOUND is documented without naming an address family. The IPv6 side is converted by the next patch, which ends its lookup failures with the same reason. Assisted-by: Claude-Code:claude-opus-5 Signed-off-by: Anton Danilov --- include/net/dropreason-core.h | 6 +++ net/ipv4/ip_gre.c | 74 ++++++++++++++++++++--------------- 2 files changed, 48 insertions(+), 32 deletions(-) diff --git a/include/net/dropreason-core.h b/include/net/dropreason-core.h index ffa11206b6ca..186d9e70e9cb 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 /** @@ -638,6 +639,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 ae50fd0f6792..e158d6e9d42a 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -264,13 +264,15 @@ static bool is_erspan_type1(int gre_hdr_len) return gre_hdr_len =3D=3D 4; } =20 -static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi, - int gre_hdr_len) +static enum skb_drop_reason erspan_rcv(struct sk_buff *skb, + struct tnl_ptk_info *tpi, + int gre_hdr_len) { struct net *net =3D dev_net(skb->dev); struct metadata_dst *tun_dst =3D NULL; struct erspan_base_hdr *ershdr; IP_TUNNEL_DECLARE_FLAGS(flags); + enum skb_drop_reason reason; struct ip_tunnel_net *itn; struct ip_tunnel *tunnel; const struct iphdr *iph; @@ -290,7 +292,7 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_p= tk_info *tpi, } else { if (unlikely(!pskb_may_pull(skb, gre_hdr_len + sizeof(*ershdr)))) - return PACKET_REJECT; + return SKB_DROP_REASON_HDR_TRUNC; =20 ershdr =3D (struct erspan_base_hdr *)(skb->data + gre_hdr_len); ver =3D ershdr->ver; @@ -307,12 +309,12 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl= _ptk_info *tpi, len =3D gre_hdr_len + erspan_hdr_len(ver); =20 if (unlikely(!pskb_may_pull(skb, len))) - return PACKET_REJECT; + return SKB_DROP_REASON_HDR_TRUNC; =20 - if (__iptunnel_pull_header(skb, - len, - htons(ETH_P_TEB), - false, false) < 0) + reason =3D __iptunnel_pull_header_reason(skb, len, + htons(ETH_P_TEB), + false, false); + if (reason) goto drop; =20 if (tunnel->collect_md) { @@ -328,7 +330,7 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_p= tk_info *tpi, tun_dst =3D ip_tun_rx_dst(skb, flags, tun_id, sizeof(*md)); if (!tun_dst) - return PACKET_REJECT; + return SKB_DROP_REASON_NOMEM; =20 /* MUST set options_len before referencing options */ info =3D &tun_dst->u.tun_info; @@ -354,19 +356,22 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl= _ptk_info *tpi, =20 skb_reset_mac_header(skb); ip_tunnel_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error); - return PACKET_RCVD; + return SKB_NOT_DROPPED_YET; } - return PACKET_REJECT; + return SKB_DROP_REASON_GRE_TUNNEL_NOT_FOUND; =20 drop: - kfree_skb(skb); - return PACKET_RCVD; + kfree_skb_reason(skb, reason); + return SKB_NOT_DROPPED_YET; } =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) +static enum skb_drop_reason __ipgre_rcv(struct sk_buff *skb, + const struct tnl_ptk_info *tpi, + struct ip_tunnel_net *itn, + int hdr_len, bool raw_proto) { struct metadata_dst *tun_dst =3D NULL; + enum skb_drop_reason reason; const struct iphdr *iph; struct ip_tunnel *tunnel; =20 @@ -377,8 +382,10 @@ static int __ipgre_rcv(struct sk_buff *skb, const stru= ct tnl_ptk_info *tpi, if (tunnel) { const struct iphdr *tnl_params; =20 - if (__iptunnel_pull_header(skb, hdr_len, tpi->proto, - raw_proto, false) < 0) + reason =3D __iptunnel_pull_header_reason(skb, hdr_len, + tpi->proto, raw_proto, + false); + if (reason) goto drop; =20 /* Special case for ipgre_header_parse(), which expects the @@ -401,40 +408,42 @@ static int __ipgre_rcv(struct sk_buff *skb, const str= uct tnl_ptk_info *tpi, tun_id =3D key32_to_tunnel_id(tpi->key); tun_dst =3D ip_tun_rx_dst(skb, flags, tun_id, 0); if (!tun_dst) - return PACKET_REJECT; + return SKB_DROP_REASON_NOMEM; } =20 ip_tunnel_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error); - return PACKET_RCVD; + return SKB_NOT_DROPPED_YET; } - return PACKET_NEXT; + return SKB_DROP_REASON_GRE_TUNNEL_NOT_FOUND; =20 drop: - kfree_skb(skb); - return PACKET_RCVD; + kfree_skb_reason(skb, reason); + return SKB_NOT_DROPPED_YET; } =20 -static int ipgre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi, - int hdr_len) +static enum skb_drop_reason ipgre_rcv(struct sk_buff *skb, + const struct tnl_ptk_info *tpi, + int hdr_len) { struct net *net =3D dev_net(skb->dev); + enum skb_drop_reason reason; struct ip_tunnel_net *itn; - int res; =20 if (tpi->proto =3D=3D htons(ETH_P_TEB)) itn =3D net_generic(net, gre_tap_net_id); else itn =3D net_generic(net, ipgre_net_id); =20 - res =3D __ipgre_rcv(skb, tpi, itn, hdr_len, false); - if (res =3D=3D PACKET_NEXT && tpi->proto =3D=3D htons(ETH_P_TEB)) { + reason =3D __ipgre_rcv(skb, tpi, itn, hdr_len, false); + if (reason =3D=3D SKB_DROP_REASON_GRE_TUNNEL_NOT_FOUND && + 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); + reason =3D __ipgre_rcv(skb, tpi, itn, hdr_len, true); } - return res; + return reason; } =20 static int gre_rcv(struct sk_buff *skb) @@ -453,16 +462,17 @@ static int gre_rcv(struct sk_buff *skb) reason =3D gre_parse_header(skb, &tpi, false, htons(ETH_P_IP), 0); if (reason) goto drop; - reason =3D SKB_DROP_REASON_NOT_SPECIFIED; =20 if (unlikely(tpi.proto =3D=3D htons(ETH_P_ERSPAN) || tpi.proto =3D=3D htons(ETH_P_ERSPAN2))) { - if (erspan_rcv(skb, &tpi, tpi.hdr_len) =3D=3D PACKET_RCVD) + reason =3D erspan_rcv(skb, &tpi, tpi.hdr_len); + if (!reason) return 0; goto out; } =20 - if (ipgre_rcv(skb, &tpi, tpi.hdr_len) =3D=3D PACKET_RCVD) + reason =3D ipgre_rcv(skb, &tpi, tpi.hdr_len); + if (!reason) return 0; =20 out: --=20 2.47.3 From nobody Thu Sep 24 14:25:20 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 0EC6C51AFCD for ; Tue, 22 Sep 2026 22:15:34 +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=1790115348; cv=none; b=i8XpN+HcMOEi6X19cY2MyAlZY1IPjgrTRq4RuOHoD8zehvr+i2UoTWAqCAO94LHbzT9HLyuY8XcjhLrpTLSSP+SzJnO3Py0157G8AiV+6bNwFkBwmsrYMvG8UFP6oz9iHz36OLXDSwgNyK0EAmPXVlmcQbFjbbVE9C0ukEMpBcw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790115348; c=relaxed/simple; bh=akINBqH8bKfMHpiHPFyy54jfDwjI28R2M536K1lp2iE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=UMqV2BhgfbUBf8aE7R22eIjigIIpuauSmDz8PNFFJLAz6BIrmEZf6zPWUkV8VsutCaQEhhPrIJLIk8AS+xTsDYDFujMKTmAAFy7Io0Ki+MbEH5wCelvN8C13MlMeq+9rHXX8lcvtndlW7APwDvF1WJjSmmzolW+1vXgvrhOu2ek= 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=JZTOsYQD; 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="JZTOsYQD" Received: by mail-lf2-f12.google.com with SMTP id 2adb3069b0e04-5b5e4f15cfdso214938e87.3 for ; Tue, 22 Sep 2026 15:15:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1790115329; x=1790720129; 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=gKznpZ+XHs6sEOlMTkDpywIxPliYUfO/kSnJjfO+euc=; b=JZTOsYQDxxuN+jAso/LmR778lp/npsMkPJjY+fkUqpFzcTFu6v1Yzop0hLrJPY4VU1 u083EhY6gKMVFNNS59RDvfwbF7gkx+oR1QadZRF4r7QdQR0CNWR9V48IPf9XpvbHNI3I 6Rqp5Pdgg6dmhEDEa84SdtPKGnHTL7llNGGzcN0RA3u52Lb5U296Elz+9KX1fAIICL04 Bj4iigj0GORO++tPsm00HyiOfZVUWwzV3eNsb7a9RDxGCjKrBmqk0xLMzOisYuNFiw1E Udn5rgiLQyViTh6bsL81KB1LhrM6+NYnV96P8N/fWX/IRxYQkPWp8oZUqI1MzqJIxAbb N8Xg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790115329; x=1790720129; 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=gKznpZ+XHs6sEOlMTkDpywIxPliYUfO/kSnJjfO+euc=; b=PGrk9YD/LEqYrz4NXTC/GLYY9i5S5KJwgmXS6DGJwg8HSPKuA4UTErtFJR6HAtxrj1 yIrv7snib7ZlHpPd0JP8SrqxbDblUWFMFYrYTva/X+GVXpIDV41YHVUbVf5y/Pml7qux 2OEBP+wfLeYLcRVYDL7mJTyzcToV7M90dnTU+qwn+e1pPp0F34CE5xLUeOb6JQx8LgUi wYDCLwaubDLW0Gc7X8SWrOyMgxCeULJAg14EzuPj3OzR06AvEYW9ewwHOG2ajjxigG8I EI6Zhhhe6cEuKHamKziRtJfo1QPID//akdd4gMUrfrR7rB/WRO1KMylNAQgc9mner5Xz +NAg== X-Forwarded-Encrypted: i=1; AKwUvBz8XECWVR9RIUpNv9gYFn8N2Lgyqb9SpGhWtrDmZaO9rqOizQMvzDbcjbOiDlq/tf7AeKsSU6ppHK8uF/E=@vger.kernel.org X-Gm-Message-State: AFuF++nwMNnQinh9IPQl04Rff7WuY2ivoAVZ1ut7D2K/C03HXCSO8hGC KOSb/1VO1icheubM9hdf50rhSkT37O0y5zmQtbT8HFLBY3dvFWBMrliP X-Gm-Gg: AYBFou054fwkguZh6RbFWqU1xkw2mD68EgqZd0MibJxcZUiF0jmTazXE5nMBm2j8Aw5 7TPGFxPQubdhhgILWO0gWOt6HoXyBtiKGFLmUmJxjrrT8ZXmKX2gcLCdUK2HPZe1Lxl7eW0rEEg D7xvvEaeAhaF5i/Qdddy9CWItbV6MtzGHGvwSOjZdkjCiwAuzkffefzcCMmBMP54qB+O87I5tzH Ps95IN9mC5YfUkoJ61XlIEcAgDfb7L2DchgHPtG2dhNtkiUWqpk0jQTuaFkN81TjnuMTJbA16K4 VGd9YSMDFdQXoYBd7xlylNfkdw2h0rn/Q4SwubbEIzo5pCtEqJGLTjLy6IimuIOvCrxevtv7Yi+ XdvqmSpStg5dmQwpddS5MPa5DXI06khHPhjKbFjO8xQmOMDCnbIoMfSuDulgOMkiArkHTU6m9MV nXXJFa4825KQAlokSRRREuT56HC+wFD8LYvyYpU4uqyixzhDWIcCJ/VBib0AQnX4A6ii84V+nWk tJN8l5Yj1RDZUABAt+k/19On53HQXVerhcgL46dHIuNirXaZCkiW1FhYrluGr9raMUYsXQk X-Received: by 2002:ac2:5696:0:b0:5b6:1a7c:59db with SMTP id 2adb3069b0e04-5b8d89c2a3dmr212402e87.53.1790115328718; Tue, 22 Sep 2026 15:15:28 -0700 (PDT) Received: from dau-home-pc.megasoftware.org ([94.28.220.48]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b8d857873asm164920e87.17.2026.09.22.15.15.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Sep 2026 15:15:28 -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 v4 06/10] ip6_gre: add drop reasons to the RX path Date: Wed, 23 Sep 2026 01:15:03 +0300 Message-ID: <20260922221507.3268127-7-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260922221507.3268127-1-littlesmilingcloud@gmail.com> References: <20260922221507.3268127-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. So far gre_rcv() reported the drops below as SKB_DROP_REASON_NOT_SPECIFIED, all from the same kfree_skb_reason() call. Now it reports: - SKB_DROP_REASON_GRE_TUNNEL_NOT_FOUND when no tunnel matches, - SKB_DROP_REASON_HDR_TRUNC when a header is too short, - what __iptunnel_pull_header_reason() returns when the pull fails, - SKB_DROP_REASON_NOMEM when the metadata dst cannot be allocated. Unlike ip_gre, gre_rcv() calls the helper before the tunnel lookup, so a packet whose ETH_P_TEB inner Ethernet header or WCCPv2 extra word is cut short is reported as SKB_DROP_REASON_PKT_TOO_SMALL whether a tunnel matches or not. Like their IPv4 counterparts, ip6gre_rcv() and ip6erspan_rcv() now return SKB_NOT_DROPPED_YET where they returned PACKET_RCVD and a drop reason where they returned PACKET_REJECT. That leaves PACKET_RCVD, PACKET_REJECT and PACKET_NEXT without users, so remove them. PACKET_REJECT has the value of SKB_CONSUMED, and a stray one in a function that now returns a drop reason would build silently and be traced as a consumed packet. Assisted-by: Claude-Code:claude-opus-5 Signed-off-by: Anton Danilov --- include/net/ip_tunnels.h | 4 ---- net/ipv6/ip6_gre.c | 46 +++++++++++++++++++++++----------------- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h index c68031d01c39..27a9e097996b 100644 --- a/include/net/ip_tunnels.h +++ b/include/net/ip_tunnels.h @@ -207,10 +207,6 @@ struct tnl_ptk_info { int hdr_len; }; =20 -#define PACKET_RCVD 0 -#define PACKET_REJECT 1 -#define PACKET_NEXT 2 - #define IP_TNL_HASH_BITS 7 #define IP_TNL_HASH_SIZE (1 << IP_TNL_HASH_BITS) =20 diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index d36949cbe9fa..ada48e23ca9d 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -451,7 +451,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 enum skb_drop_reason ip6gre_rcv(struct sk_buff *skb, + const struct tnl_ptk_info *tpi) { const struct ipv6hdr *ipv6h; struct ip6_tnl *tunnel; @@ -471,22 +472,22 @@ static int ip6gre_rcv(struct sk_buff *skb, const stru= ct tnl_ptk_info *tpi) =20 tun_dst =3D ipv6_tun_rx_dst(skb, flags, tun_id, 0); if (!tun_dst) - return PACKET_REJECT; + return SKB_DROP_REASON_NOMEM; =20 ip6_tnl_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error); } else { ip6_tnl_rcv(tunnel, skb, tpi, NULL, log_ecn_error); } =20 - return PACKET_RCVD; + return SKB_NOT_DROPPED_YET; } =20 - return PACKET_REJECT; + return SKB_DROP_REASON_GRE_TUNNEL_NOT_FOUND; } =20 -static int ip6erspan_rcv(struct sk_buff *skb, - struct tnl_ptk_info *tpi, - int gre_hdr_len) +static enum skb_drop_reason ip6erspan_rcv(struct sk_buff *skb, + struct tnl_ptk_info *tpi, + int gre_hdr_len) { struct erspan_base_hdr *ershdr; const struct ipv6hdr *ipv6h; @@ -495,7 +496,7 @@ static int ip6erspan_rcv(struct sk_buff *skb, u8 ver; =20 if (unlikely(!pskb_may_pull(skb, sizeof(*ershdr)))) - return PACKET_REJECT; + return SKB_DROP_REASON_HDR_TRUNC; =20 ipv6h =3D ipv6_hdr(skb); ershdr =3D (struct erspan_base_hdr *)skb->data; @@ -506,14 +507,16 @@ static int ip6erspan_rcv(struct sk_buff *skb, tpi->proto); if (tunnel) { int len =3D erspan_hdr_len(ver); + enum skb_drop_reason reason; =20 if (unlikely(!pskb_may_pull(skb, len))) - return PACKET_REJECT; + return SKB_DROP_REASON_HDR_TRUNC; =20 - if (__iptunnel_pull_header(skb, len, - htons(ETH_P_TEB), - false, false) < 0) - return PACKET_REJECT; + reason =3D __iptunnel_pull_header_reason(skb, len, + htons(ETH_P_TEB), + false, false); + if (reason) + return reason; =20 if (tunnel->parms.collect_md) { struct erspan_metadata *pkt_md, *md; @@ -530,7 +533,7 @@ static int ip6erspan_rcv(struct sk_buff *skb, tun_dst =3D ipv6_tun_rx_dst(skb, flags, tun_id, sizeof(*md)); if (!tun_dst) - return PACKET_REJECT; + return SKB_DROP_REASON_NOMEM; =20 /* MUST set options_len before referencing options */ info =3D &tun_dst->u.tun_info; @@ -558,10 +561,10 @@ static int ip6erspan_rcv(struct sk_buff *skb, ip6_tnl_rcv(tunnel, skb, tpi, NULL, log_ecn_error); } =20 - return PACKET_RCVD; + return SKB_NOT_DROPPED_YET; } =20 - return PACKET_REJECT; + return SKB_DROP_REASON_GRE_TUNNEL_NOT_FOUND; } =20 static int gre_rcv(struct sk_buff *skb) @@ -572,19 +575,22 @@ static int gre_rcv(struct sk_buff *skb) reason =3D gre_parse_header(skb, &tpi, false, htons(ETH_P_IPV6), 0); if (reason) goto drop; - reason =3D SKB_DROP_REASON_NOT_SPECIFIED; =20 - if (iptunnel_pull_header(skb, tpi.hdr_len, tpi.proto, false)) + reason =3D __iptunnel_pull_header_reason(skb, tpi.hdr_len, tpi.proto, + false, false); + if (reason) 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, tpi.hdr_len) =3D=3D PACKET_RCVD) + reason =3D ip6erspan_rcv(skb, &tpi, tpi.hdr_len); + if (!reason) return 0; goto out; } =20 - if (ip6gre_rcv(skb, &tpi) =3D=3D PACKET_RCVD) + reason =3D ip6gre_rcv(skb, &tpi); + if (!reason) return 0; =20 out: --=20 2.47.3 From nobody Thu Sep 24 14:25:20 2026 Received: from mail-lf2-f13.google.com (mail-lf2-f13.google.com [74.125.229.205]) (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 1B9DB491587 for ; Tue, 22 Sep 2026 22:15:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.229.205 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790115343; cv=none; b=ly4NGj33uHWJzIIiwd9MMdfnQoAPAtWAMmvl0W4i+Qhv0++412/GXGNKlatGBfJmBKRql8LM7Mjo5doNbcHo6cT3dJzRMh3B1sesElt784g5JGZFpRRptK2wzEVBFNBZWCoSxEWh6EhUYX5aHUWokFAiTj98cafUg3DMh9EOvFw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790115343; c=relaxed/simple; bh=+ZYr9hJlpv3Thm/GkJbA604cP63Bciii/9KwgO3P1ko=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lObFiQZsmONdm5Y8lVoc1JD/mNcXcZPduN8rHyQIoF4yjNxPORnXHzn4na/b4hequbc238XabbThBHSmWMQdaat/psmNr2ev1fVBY83ry8P+8di034+HMxIgi9rQqyH2OFNsXm7+hZ/5AGtGanOOvtAxTpbls9sVIFJmlsy4meY= 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=XE4QHk2f; arc=none smtp.client-ip=74.125.229.205 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="XE4QHk2f" Received: by mail-lf2-f13.google.com with SMTP id 2adb3069b0e04-5b8d47b5987so225156e87.2 for ; Tue, 22 Sep 2026 15:15:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1790115333; x=1790720133; 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=kTTJsYrMOcak4ZY4X29CZhZYIBW9UPLBMkRtT7ScOWU=; b=XE4QHk2fUCk6+hLCFc4dlwi7Dz/BDwPd4kNIRLsxQ38NSHO9JjpYtq8wT+8q77O+m9 KAhW5f7RKjSKIoTbdGQcq0uuPJkP/2B8pTexEXYmYRIV5td9YZ8sv0QCO0+TLbwqsnXY R1LJmiCJ49Z5FDir8NyjZCrVRturEOL6y7wCKx7bXQpwuCbncOrlDS52bLAT6wcHHSAL ybTQ3nyBQDyEgdYOixKIfzeAKm/o1A5xGucZDadmosdHYQQnriPgWDXaczn8JbDPi7I5 8o2utXhYXADw55YCko2TZoaYWpFmwBy4pxjZ6ICjPNLTLCR2tuo54KJ4zejRgxzqouux +x4Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790115333; x=1790720133; 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=kTTJsYrMOcak4ZY4X29CZhZYIBW9UPLBMkRtT7ScOWU=; b=XxxgJFFz7djRDt6oenOWLS7OL0ZXngYLTfpAqFMLZom6+OJUxoHIdHnkAxB4ZxMJ28 3VEZCieAgXYh3lMoRhrfM1vE56AuMZYlCfEfb5AqCUcYHjY2ot+pj8pIfYhWTMSNNS2p 9OSgn00eKmZ6KzpjZPa1HXfS8i8sL0GEuCwHR0DiktYDb1ZJvnAgabXY3JylNEkn90NK 8bVqWVC3qX9vWoO9HaZvZQMHFHcOdRXgr/N5VuYjAdouuLKelz2/SfmxZhtX1YQlx+pz yadMp/0VizTYbzPCoICB4nmCTLxCGXFjiJTorRCNFv9XgPXUNTM/VmHNRnafKLJCTHp+ aEpQ== X-Forwarded-Encrypted: i=1; AKwUvBzKM1d1k63peL4ljItPtcfYJB/ba5icikLilCntehPJ5/YEt2D3X2a3AquZgwzGTsAut57GeC6Zouc+PSM=@vger.kernel.org X-Gm-Message-State: AFuF++narCNE7mKjrtuldVJsC+65++Xn9p6oNzoETSi6BF9pmLoLqptB 2Nnvxc1EJBVcF7aF2R4Q/LW1Zcj7vsohUA1cGFmkyUlCuZQ15bB3Qgms X-Gm-Gg: AYBFou3UFFUQGX+aeGy4rvm4NUqTK3p08mkXmNWkqYSZzkK0iSTd7jr4x9bSe3q+Jfn redDRGVlc6pX+q2jp5coFKL7UOVye8CSLA6EOn+te89Eaa46HxOoW4sLtbTh+Oq4924rwfz60HA oG4rx2on2Tbs/ziD3LFbdIGiRUGmi11Wy88LPsVWWTRgRSh+y01gIEHTOn9gglQCHNBpb4nOZQ7 Yjxmby6al8w0dinfgYPTSX6S0HrbYjQLPHgH+YRt9HJhSN4dw3YiFzZYIwvm3cZRSNStdsx/eDe d2Z2FljKuXEmn+qAg+LNrcLF+i6Joa6b46k5VtUh+8oFCNV68tgxz3NnI4bK1uZaGQfu3855RcR 7Ssp4+svXpkZzopQr1MohvSK8lIy6F44lUAKxtrRmmrQRalEXTUP1PsFKQrNyULsJJTdVs1N4q8 AywyPG13lV8XlEtEi/h+Qc3CUHRqRv3cij6NBsQZP0dt0hXpvGn6Lo4iU8reds3oBMBJWEUDPk8 gg/Jwfdcn9xauQogVUrLieDfkdvRbJWJo3fo+JKNYSQwUR2pRgeyGfgh1YCXw== X-Received: by 2002:a05:6512:3ca5:b0:5b6:1a7c:aa1d with SMTP id 2adb3069b0e04-5b8d89a8001mr188921e87.53.1790115332677; Tue, 22 Sep 2026 15:15:32 -0700 (PDT) Received: from dau-home-pc.megasoftware.org ([94.28.220.48]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b8d857873asm164920e87.17.2026.09.22.15.15.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Sep 2026 15:15:30 -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 v4 07/10] ip_tunnel: add drop reasons to the transmit path Date: Wed, 23 Sep 2026 01:15:04 +0300 Message-ID: <20260922221507.3268127-8-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260922221507.3268127-1-littlesmilingcloud@gmail.com> References: <20260922221507.3268127-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 the packets sent through the tunnel, and every failure these two functions detect ends in a plain kfree_skb(). The device counters separate them a little, but they are too coarse to act on: tx_errors counts an encapsulation failure, a routing failure, a routing loop and a packet that is simply too big alike. The packet that is too big deserves attention. tnl_update_pmtu() returns -E2BIG for a non-GSO packet larger than the MTU if it is IPv4 with the DF bit set, or IPv6 and the MTU is at least IPV6_MIN_MTU, after it has already sent the ICMP error back to the sender. That is path MTU discovery working as intended, yet among the device counters the drop only bumps tx_errors, like a failed encapsulation and a few other failures do. If the ICMP error never reaches the sender, the resulting MTU black hole cannot be told from those by the device counters. A failed route lookup and a routing loop do have counters of their own, tx_carrier_errors and collisions, but in both functions all of these packets end up in the same kfree_skb() call. 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 the route lookup fails, - 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, on the same NBMA path, 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. They are most useful for forwarded packets, which is what a tunnel gateway mostly transmits: the sender is another host, which gets an ICMP error for only some of these failures, so the drop has to be explained on the gateway. 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 186d9e70e9cb..a72b84b07daa 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 /** @@ -644,6 +645,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 c94f4c055027..66cb0b86fa79 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -586,6 +586,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; @@ -599,8 +600,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); @@ -619,8 +622,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) @@ -629,6 +634,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) @@ -638,6 +644,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 @@ -646,6 +653,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 @@ -663,6 +671,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 @@ -677,13 +686,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; @@ -711,9 +721,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 && @@ -734,8 +750,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); @@ -752,8 +770,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 @@ -780,8 +800,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); @@ -798,6 +820,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) @@ -811,6 +834,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 @@ -820,6 +844,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 @@ -854,7 +879,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 @@ -870,7 +895,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 Thu Sep 24 14:25:20 2026 Received: from mail-lf2-f13.google.com (mail-lf2-f13.google.com [74.125.229.205]) (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 7E2DE522691 for ; Tue, 22 Sep 2026 22:15:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.229.205 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790115352; cv=none; b=RE7mxkkdV70pEISf9sfg0tHmnQ5cW7bZjfI8U00bL+3WF/N4DgAnUWj+78g155Ty5ccsEfR3pFV2uWDZ9inbdS0w35T9lu4XmNdBGfPsqKs8YuqUVnfLUlDQPAAoyYEQ3nhOOMsLf1gC+2zq2f3jyyAV0ssne3pMdi0EGTjzkOY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790115352; c=relaxed/simple; bh=OW2CuFCCxfYS9SdBfkXjwwy6lIRLZuhaoeGNoJ5XxbY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gD6PpsVHKWK8Zba/Ue4rU57rmDrIwLT7yCBDlhHdcEjk9AWUO9MBnlUPb4o0MJlI0Yzgmq7L6rj0KZeTimIwb0F/hXyc26Kutx5vHru3/bFf0yYvDQRjn3J851pRAPsK7kOqHNvGlqEi3MeGBesgcacuCtzwom8pznpAG1FN87A= 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=lpG5Q0Sn; arc=none smtp.client-ip=74.125.229.205 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="lpG5Q0Sn" Received: by mail-lf2-f13.google.com with SMTP id 2adb3069b0e04-5b8c1b8d7b5so265872e87.0 for ; Tue, 22 Sep 2026 15:15:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1790115335; x=1790720135; 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=EFYqjKXJT0aHpkGiNFipCh7kFpFVgjGz3iETsztdd8M=; b=lpG5Q0Snj6h+gWT+z9f8RiDWOfiq92gcr7+K/F/9FIzBvyRcEoq7Yi/0eCCQergndt G0YAPRT5FFKr/pRFI+Ptl34yqdl83hAIGhUcm5duCT3dAmROYDt5rGtR/1LDh0IAhr2S fMINOuleFBANuPBjneelGvkb6aYVBE6qwMbLrTX9HMXtDfoA9iQb2jm5Fnen3muaVGQL MwlhUDQVcmL7lB6AcX+Xpuy2V42IFZQVWGLrTL8iSXjwncwQ4aQmnU1BHjvXwHPK/yDO YenTeHWqh31HgyklJ+PVKJRSH2zMDs89WQ6WX1zwbDxtukBsGyl4Elc6upQb+B/E1RkQ qKxg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790115335; x=1790720135; 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=EFYqjKXJT0aHpkGiNFipCh7kFpFVgjGz3iETsztdd8M=; b=pzgg/plkHvqceNEu+TFDTtkwPLwLLYEXKTbMYJNQzfW294hLItYCr71Fxk9s6ZWfXV Rz33XX8heUlZCGUgKoK6N68rgkWmFKWLpJI5cKhVwTkaM7LAT3r/IDQX9eV6tu0fXX41 A3aUuydaiGUKhdqinzAIyByPoip39onZBRtfjAA2zbiLmmoaheuxV8OjqE+4bygvxOmk rHZhqzI/bw/jSsqFGppidqCf6zrXBw9l+zDWjx3N+lQWDXZhDzzDYRCFTiUGJ2kV4GKL p9kCOmkS4cDoP7xVhhw++j9aeuIJqHmjwAr+sBWW9VeU2pjRzNYPQN1CSidcnBeq6puF 02Fw== X-Forwarded-Encrypted: i=1; AKwUvBwtPFUqy2bKDYvvpAcA1J+3DUBso7FUpydKTBO46KxXSWrqq5dmbYL+wwPwGQ4WkQ0z15Es3MZrP6EqQ34=@vger.kernel.org X-Gm-Message-State: AFuF++mgt3fPf8VIEwCutnMoxzYxjzX49oCuvqeRiy8PzDWIH3US/gz2 otUoLtYhuKq4gARmn4R2/GWDwcvD98lHJbBSnwKSXw3w4b76ttXwBAHf X-Gm-Gg: AYBFou0zRFo7RKQh9mLQGZx7zLwn/ezv3aA3X0Yxq5p1XerTOA8UnDr5pjq75zJ0Y/g 0WRiNdwWoJoI00AYGSz7+H5mYt4K3VUngbzGL/582NznpUr0vX0LDPCpaseY5IFLRclvGapxbhf Vz/g+wSLLekFAbarM7F8FnHjoisL+RGORCbHUMkT1lDdxlsq6peKwG7kziv+3vhDHHcJvzqWdhm U31f42F7Y0lBvWu8iyuyhVTLd21AumvUGrbaEpcPeYxjkV2mVw+BU9I6Wrmshx4DlvMbcNGocmc isHBzOhmUclqjonOFzEwFELACu57+8c65pdoIMdoJjPJ5WQFoxFNnRGrh+OduHiur33My1Z1hZv xS8rZjaYpuqbugCkVBeR1L5xOhX+lnOCuUWatlYHzF5Qy9E6SRqQtoawuIt8uLO0X0WJGo+B8wr bRzjZufZdA8+1vKKLVCh+PMCZQRvmZC2w8SPZfD4I3wXF6QzxYkM75LTT317t/yk8/WJmWXJ9V4 zRGB4PJUyJcjoyxVI0DVwQQeEQW4M1qeajVNW/RaCSao6Tv+yl6BwLHmB5wEDFwf5HY2vju X-Received: by 2002:a05:6512:61c8:10b0:5b4:ac27:6bb0 with SMTP id 2adb3069b0e04-5b8d897bcb6mr153177e87.25.1790115335072; Tue, 22 Sep 2026 15:15:35 -0700 (PDT) Received: from dau-home-pc.megasoftware.org ([94.28.220.48]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b8d857873asm164920e87.17.2026.09.22.15.15.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Sep 2026 15:15:34 -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 v4 08/10] ip_gre: add drop reasons to the transmit path Date: Wed, 23 Sep 2026 01:15:05 +0300 Message-ID: <20260922221507.3268127-9-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260922221507.3268127-1-littlesmilingcloud@gmail.com> References: <20260922221507.3268127-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" Each transmit function of ip_gre ends all of its failures in one kfree_skb() and a tx_dropped increment, so a drop can be traced to the function and to nothing more precise than "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 e158d6e9d42a..ad669b3f8757 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -506,6 +506,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; @@ -514,19 +515,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); @@ -543,12 +550,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; @@ -562,29 +570,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 @@ -616,6 +636,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 @@ -628,7 +649,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 @@ -659,11 +680,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) { @@ -674,10 +697,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; @@ -687,25 +713,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; } @@ -713,12 +745,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) { @@ -726,15 +760,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 @@ -755,6 +795,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 @@ -763,7 +804,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; } @@ -771,10 +812,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) { @@ -784,17 +827,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 Thu Sep 24 14:25:20 2026 Received: from mail-lf2-f13.google.com (mail-lf2-f13.google.com [74.125.229.205]) (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 D41EC41D647 for ; Tue, 22 Sep 2026 22:15:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.229.205 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790115357; cv=none; b=f3xZxhEwUiQ8RTG25r9JoZbZNWj2CO/swyJ+fO2w7uu9o0TVqaBNW/lygjQ7tmugMATh36kVFZWGWlmoG29Oi+arKBDO8L5r1u0rPEitmdZXxJHuco6c7aYMcPt4MvtCnystIZGCAr7h0f37/vKxRT7+N+sGep6e2tCHOpSyqT8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790115357; c=relaxed/simple; bh=xE30Qt7zIKt7pcnaioEffY8ZCWbCqOVSLJObXoIb9Gw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=uGAjMZ4ziF67+jyO0PGhNyaM/Po8cwoCv0fhb+WPuZ3bkh3DcIe/y4b2/OaDb8GcQTNuS5USapGQ36KgSNGN6wVOd2aa5uzQ9X81AXEHKyw3kC9eQsD8vFg+hUwnHDDNbNZ6JKKjuy2E3DxYm1e7X1eI9ed6v7vTUPWW6iCgkSY= 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=TQO268wz; arc=none smtp.client-ip=74.125.229.205 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="TQO268wz" Received: by mail-lf2-f13.google.com with SMTP id 2adb3069b0e04-5b5e4f16f15so249617e87.3 for ; Tue, 22 Sep 2026 15:15:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1790115339; x=1790720139; 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=6cYu/7TP7+XgfZfRQNvsk21Nb8kX34KuhCY2JK6GjCk=; b=TQO268wz7ijZ2WFJ2nzXAZ3uvT/f/L2Dv+0hvE1x2eN38XA8mG+gLOh/Nct5NHXH+n GLPqrwSRVx654G6QK8Ww2VWgLYR0H3XrC73sa8FndN2KR3LDxvlA/cYEfS6Of9r6qYZM 5RkGjNiQ9yxbs6YcQ49i8g05j85VUL4sGx5lWMofPVyoTIYT0DpYPbmg5s11h6mTnIH7 4XwoTajni7yrT6502TKzeC9mZJq+86FGsCeHQl3vE1kigBzhIfcuWJHSq5C4z75sR04z lfolpKu+xOl7ZzmwTlGU1RFfYHhG54RKaNjty2QRKc6lwkjpZIwRLkGAZAqXe2QccMj4 OYJw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790115339; x=1790720139; 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=6cYu/7TP7+XgfZfRQNvsk21Nb8kX34KuhCY2JK6GjCk=; b=USbbOM3V6eIShkDBaMZXeNsFC2auNaVgukbyj6Dhu/SHBmYUl5996uOjqUADsBENjk Sm1YCrVaDKaAliCPNHKNfXTKjC3LI3/6AgwifHw73NhMJW9/tIsoG+IetSM5FUaKfNcM 0AMH2aV5lesAIkbzBv2LAE0Py0xwwhJKhaKrQAg0vXvvtkqPRQDIj9pPymF7XqJi0THv cwjIlBnTdJ5T296C2c501NdPF5DmyHUJ4lqNaQTjdxNers8BQoCE4DQiy6BJVvswhkup oj8BntZKlm+gohyDD7V+H0J2iVNyqsqBQ4HcoURsdSfik841j3I0mRlwFTcNz6DJZWeA TgUA== X-Forwarded-Encrypted: i=1; AKwUvBym4uhwF3HEmh9PtCycHgMVE8mFaE/yhNOBn0mSHFW/RfRf5UVoBKoeS2fPBRmhq/6EJH2HVsnHSR3kQ88=@vger.kernel.org X-Gm-Message-State: AFuF++mp/p3IjFIhkEnfWmoCtGZbgktgffWm83Ihx8WAkPK6Q2s0YqM0 gsipkJnGA1P+LN7tDagIeSgcNgJBv7JourGxicQhBsAzO0yQTou6voidkZlspVmCQSg= X-Gm-Gg: AYBFou3rVfW9ZToRcfFpx7MXey2Suwa5e2qWn4Tq4rhT5u8vkf2sbWMFUY+agCwJJ+C Sx9m9wWtsa2jufW25tW8lrZH7C73T//7CpkMDXiAb0pG0BFbsO62IReL8Cn+eEOVYIZnVG2zbRn vaWCMz0B+bxe4PieXTnJ98mmlCEAXaEoviDns+WP8R18thaMTlL3rGU/oPAvhHWo9sU5c3wq628 1LuybNGwKhtz2/ZIPesgi+bttHAWQR/aclz1cJ+ULXgh1lXc5+NoFxaITqsWQqqpPC+bblkbrEs eA7lN5VVkMYqTthGj3Z0nE4ZaYgU3kqWzFfXbGhsgbpwQqSLDSSdcncNJD29XbAss+l6GRUrjey w7mxs8XxVv1UDGOPdde/fwqtQg5D6uZNKhDI13bgoms4K2h6LDFEwmuM1f1uuHEhtQz5+IXTHJ9 8YjTdyP4/KDcXSjqC0x0jAA9zZqTbzbgRmMatVzbT3VS8tL45U8X0GWh0akhiAMbETdhOaQFgtM vmWpgmMuONZkHgkvvFiWl/2pRhK2og1lmX1Acq4PZMaXKWVQBLmlXAOpPT6TQ== X-Received: by 2002:ac2:5696:0:b0:5b8:bc5e:d10b with SMTP id 2adb3069b0e04-5b8d89c2dbemr219604e87.53.1790115338639; Tue, 22 Sep 2026 15:15:38 -0700 (PDT) Received: from dau-home-pc.megasoftware.org ([94.28.220.48]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b8d857873asm164920e87.17.2026.09.22.15.15.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Sep 2026 15:15:36 -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 v4 09/10] ip6_gre: make prepare_ip6gre_xmit_other() void Date: Wed, 23 Sep 2026 01:15:06 +0300 Message-ID: <20260922221507.3268127-10-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260922221507.3268127-1-littlesmilingcloud@gmail.com> References: <20260922221507.3268127-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" prepare_ip6gre_xmit_other() copies the flow template of the tunnel and picks up its encapsulation limit, DS field and mark. Unlike its IPv6 sibling, which fails when the packet's tunnel encapsulation limit option is 0 and so forbids encapsulating it again, it has nothing to fail on: its only return statement is "return 0", and it has been that way since commit 41337f52b967 ("ip6_gre: set DSCP for non-IP") added the function. Its caller still checks the result and bails out on a branch that never runs. Make it void and drop the check, the way prepare_ip6gre_xmit_ipv4() is already called. The next patch gives every failing branch of the transmit path a drop reason, and this one would otherwise get a reason it can never report. Assisted-by: Claude-Code:claude-fable-5-1 Signed-off-by: Anton Danilov --- net/ipv6/ip6_gre.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index ada48e23ca9d..6a0a508e0091 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -680,10 +680,10 @@ static int prepare_ip6gre_xmit_ipv6(struct sk_buff *s= kb, return 0; } =20 -static int prepare_ip6gre_xmit_other(struct sk_buff *skb, - struct net_device *dev, - struct flowi6 *fl6, __u8 *dsfield, - int *encap_limit) +static void prepare_ip6gre_xmit_other(struct sk_buff *skb, + struct net_device *dev, + struct flowi6 *fl6, __u8 *dsfield, + int *encap_limit) { struct ip6_tnl *t =3D netdev_priv(dev); =20 @@ -703,8 +703,6 @@ static int prepare_ip6gre_xmit_other(struct sk_buff *sk= b, fl6->flowi6_mark =3D t->parms.fwmark; =20 fl6->flowi6_uid =3D sock_net_uid(dev_net(dev), NULL); - - return 0; } =20 static struct ip_tunnel_info *skb_tunnel_info_txcheck(struct sk_buff *skb) @@ -865,9 +863,9 @@ static int ip6gre_xmit_other(struct sk_buff *skb, struc= t net_device *dev) __u32 mtu; int err; =20 - if (!t->parms.collect_md && - prepare_ip6gre_xmit_other(skb, dev, &fl6, &dsfield, &encap_limit)) - return -1; + if (!t->parms.collect_md) + prepare_ip6gre_xmit_other(skb, dev, &fl6, + &dsfield, &encap_limit); =20 err =3D gre_handle_offloads(skb, test_bit(IP_TUNNEL_CSUM_BIT, t->parms.o_flags)); --=20 2.47.3 From nobody Thu Sep 24 14:25:20 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 BEC9D4B1CF4 for ; Tue, 22 Sep 2026 22:15:49 +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=1790115360; cv=none; b=J6jSavmBtM/cjbqJiFeYWPRNNO6XnYilrjaFJGWo0UrVRWvt3UjenPySSUaBg5eOaII955auMuWaqGETATXvvAhjgkjgIN2BMDYZgsG7ts33/I4KBEbc0MmnbDMWCxFkC2wat2uzJZi1pHnSlD2uc4AXHClaosWx88eFHI5/Ujw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790115360; c=relaxed/simple; bh=LYqfMz1Xf9p68ThTbvdVPQbfV51P5lpd0AW0nBgb1t0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Q7LqpLVmMf9KnEndtdF24iTcjqboYpkZa4XbsH8JRlYAoi9zlea4OOTNQ4WgjzcL705T0p6lrryXSeB/OcUQXkJL+6RjmMoCW7M8qi3v2EhSUVtOKcvZmXZU8w+bC9skex4O43Webv/nQe3VWaj0vZA2FJMJ/DBIwD55CY9IsBQ= 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=RfOd3Qr3; 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="RfOd3Qr3" Received: by mail-lf2-f12.google.com with SMTP id 2adb3069b0e04-5b5e4f15cfdso215051e87.3 for ; Tue, 22 Sep 2026 15:15:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1790115341; x=1790720141; 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=tfn824KmhJ9fBHCepYYAG7VguuAYpc4vdl723gZMDWQ=; b=RfOd3Qr34eZrYj8SIuFYyYw7C9ez/wz6ENhh/qtFr7hVxu67N8NLnybepvEYCBQBbZ +ZfIohj1TEPx5nggIApmY+gExlRnGr5ONFirP5BzZJk1MKWhCgvwkWd+iZTPGhZ/p4b4 /yKK+gV11GbL8iX/kZKSO61daoRC2xodQKFTSiJE5VFw833DHZOxecBoorJQaJZSAfTX FogQxHJIti6jwKia8S9Ahjpfoza5TblESsFQoPrhBZub17SoheGOJ/bhxF1RyT2Z2Mnl +wY2aU2TiKej/aVwWePPY2cxkHtEXLW2YYA2Yid9QFHGN9pPDEJx2x8iqBBLF9+lw/RW 67+w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790115341; x=1790720141; 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=tfn824KmhJ9fBHCepYYAG7VguuAYpc4vdl723gZMDWQ=; b=FHhq+/dufQ40F5oA85udaD6XGnysXVGKcgrxAFSo7P6QmaDZXZqNpCTLXnKYI5jrrS bKsjUUgdg0IFq9m2EeqdBH+kGq6hp7cQXgnManvkvFHZwK+vEPEzs/tucsIfWpKqTP1a vKO+0/mHHORadZcGABnSjsGjksY7pGMgdqSOIFFOyxmlhFIWRbKunvQwYXr92aPTzj40 m5Ch/lwP6dAIlpez8WhzKkxHROdBw3mxGkunJE6yu5bYf9rTLS0soJuQ5tchkhBB2XtW Rsg+QSf+zKwJnerM/gyHCF1nEoZOeoT4loIyEOIwHcNOh08fTIglcsbgLcYFQGvgG9/w B/og== X-Forwarded-Encrypted: i=1; AKwUvBxbZGUL72ErTMqO0S1/ZErMqb+zZ2DucPbB8w3qfAfm/DuRIhc4+q3DcdbDCmsBkOV4Cixh5OWmH3SunMI=@vger.kernel.org X-Gm-Message-State: AFuF++lwju5a7RQwo6xwPi89yFfDhocDNJwEKBI5KR67miBKEYH7za/O x/0hkGMrjgPdbRddxonRu+tpHr1jPw2i3B4JOg6DXMwOWO+x2VXDtfqI X-Gm-Gg: AYBFou3Uba6na7Uhe2uDQKOc4xZjy+fQD+huc/ffSSW8K0uYqAcw/lXM4lc7DXyt8Dk 2xeY+FQyMjQEhtV4j9Ze9E3PMOyrqKK72hP4fu8Dn35hjBTdk4l4aC73d7+k6K5keUlnGiV9VAz X6+o/yY1qYbgVw5vzSYFPg1Rq8FenWd7vvj+PSCMQwlbkySH+aaym/qCdW8tyO4hzXrMyt5YX9T aODWvE8s6GFr/pLlsl7Tsb0YZzO1V2dIkjFzf9gXY41R5J8QOaCfF3KJT3sVfblxeLPqiSGr8+P UrfUCqkax0b/j4XfmBSWAeIXuEvEeytK6HwKRScPG2nA5WE1ITLvppEQEAHQcwTKunMJO/Q//TG L3O/hzDXUZzWbSP/j+GAbsb7ByaRg1qj2kK4a6webJp3w7p78EDIV0HlfNsO7no+N3IeXnEsY71 K1RL0yL4gEOdnqqXvEy8e7+1+zr6gpYbbXdy+m2OqKHiPBpH4C2/ZSLX7dT8XEGGkl7h9Eh6QmJ 9gH4gC6PXd9M0smkcWUDI+66/MKtNEJiilm7DlA6xfscQ3VIcSdyknXG95hvA== X-Received: by 2002:a05:6512:6204:b0:5b8:b37f:15a with SMTP id 2adb3069b0e04-5b8d896873bmr146541e87.3.1790115341027; Tue, 22 Sep 2026 15:15:41 -0700 (PDT) Received: from dau-home-pc.megasoftware.org ([94.28.220.48]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b8d857873asm164920e87.17.2026.09.22.15.15.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Sep 2026 15:15:40 -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 v4 10/10] ip6_tunnel: add drop reasons to the transmit path Date: Wed, 23 Sep 2026 01:15:07 +0300 Message-ID: <20260922221507.3268127-11-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260922221507.3268127-1-littlesmilingcloud@gmail.com> References: <20260922221507.3268127-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. Make ip6_tnl_xmit() return the drop reason, SKB_NOT_DROPPED_YET on success, instead of 0, -1 or an errno, and do the same for ipxip6_tnl_xmit(), __gre6_xmit() and the ip6gre_xmit_*() helpers, so that the ndo_start_xmit handlers, where the packet is actually freed, can report it. The callers only told success from failure and looked for -EMSGSIZE to send an ICMP error back. ip6_tnl_xmit() returns -EMSGSIZE only for a packet that exceeds the path MTU, which is exactly when it reports SKB_DROP_REASON_PKT_TOO_BIG, so the ICMP error is now sent when that reason is returned. A failed xfrm lookup never returns -EMSGSIZE, so its errno only ever meant failure and goes away. __gre6_xmit() was declared as returning netdev_tx_t while it returned an errno, and now returns the reason as well. ip6_gre is converted in the same patch because it calls ip6_tnl_xmit() and depends on its return value. As in ip_gre, the ndo_start_xmit handlers take the length reason from pskb_inet_may_pull_reason() instead of pskb_inet_may_pull(). The other 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 and xfrm lookups, including the source address selection that a collect_md tunnel does when the flow has no source address, - SKB_DROP_REASON_NO_TX_TARGET when an NBMA tunnel gets an skb with no destination to derive its endpoint from, - SKB_DROP_REASON_NEIGH_CREATEFAIL when the NBMA neighbour lookup fails, - SKB_DROP_REASON_RECURSION_LIMIT for a route pointing back at the tunnel, and for the trivial tunnelling loop ip6_tnl_addr_conflict() guards against, a packet whose source is the exit point of the tunnel, - SKB_DROP_REASON_NOMEM for the allocations, - SKB_DROP_REASON_TUNNEL_TXINFO for the collect_md metadata checks, - SKB_DROP_REASON_TNL_ENCAP when the encapsulation header cannot be built, and for a collect_md tunnel that has an encapsulation configured, which ip6_tnl_xmit() does not support, - SKB_DROP_REASON_UNHANDLED_PROTO for a payload the tunnel does not carry, either by its mode or because it is neither IPv4, IPv6 nor MPLS, and for an ERSPAN version that is not implemented. 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 packet's tunnel encapsulation limit option is 0, which forbids encapsulating it again. A collect_md tunnel has no fixed exit point and its raddr is normally ::, so ip6_tnl_addr_conflict() and the same check in ip6gre_xmit_ipv6() also drop the packets it sends from ::, such as the DAD probes of an ip6gretap device. They were dropped before as well; SKB_DROP_REASON_RECURSION_LIMIT names the check that drops them. Assisted-by: Claude-Code:claude-opus-5 Signed-off-by: Anton Danilov --- include/net/ip6_tunnel.h | 5 +- net/ipv6/ip6_gre.c | 137 ++++++++++++++++++++++++--------------- net/ipv6/ip6_tunnel.c | 100 ++++++++++++++++------------ 3 files changed, 146 insertions(+), 96 deletions(-) diff --git a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h index d1f0a427e9c8..363eed61b296 100644 --- a/include/net/ip6_tunnel.h +++ b/include/net/ip6_tunnel.h @@ -143,8 +143,9 @@ int ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff = *skb, bool log_ecn_error); 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); +enum skb_drop_reason +ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, + struct flowi6 *fl6, int encap_limit, __u32 *pmtu, __u8 proto); __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 6a0a508e0091..31930ff813dd 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -716,10 +716,10 @@ static struct ip_tunnel_info *skb_tunnel_info_txcheck= (struct sk_buff *skb) return tun_info; } =20 -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) +static enum skb_drop_reason __gre6_xmit(struct sk_buff *skb, + struct net_device *dev, __u8 dsfield, + struct flowi6 *fl6, int encap_limit, + __u32 *pmtu, __be16 proto) { struct ip6_tnl *tunnel =3D netdev_priv(dev); IP_TUNNEL_DECLARE_FLAGS(flags); @@ -744,7 +744,7 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb, tun_info =3D skb_tunnel_info_txcheck(skb); if (IS_ERR(tun_info) || unlikely(ip_tunnel_info_af(tun_info) !=3D AF_INET6)) - return -EINVAL; + return SKB_DROP_REASON_TUNNEL_TXINFO; =20 key =3D &tun_info->key; memset(fl6, 0, sizeof(*fl6)); @@ -763,7 +763,7 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb, tun_hlen =3D gre_calc_hlen(flags); =20 if (skb_cow_head(skb, dev->needed_headroom ?: tun_hlen + tunnel->encap_h= len)) - return -ENOMEM; + return SKB_DROP_REASON_NOMEM; =20 gre_build_header(skb, tun_hlen, flags, protocol, @@ -774,7 +774,7 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb, =20 } else { if (skb_cow_head(skb, dev->needed_headroom ?: tunnel->hlen)) - return -ENOMEM; + return SKB_DROP_REASON_NOMEM; =20 ip_tunnel_flags_copy(flags, tunnel->parms.o_flags); =20 @@ -789,9 +789,11 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb, NEXTHDR_GRE); } =20 -static inline int ip6gre_xmit_ipv4(struct sk_buff *skb, struct net_device = *dev) +static inline enum skb_drop_reason ip6gre_xmit_ipv4(struct sk_buff *skb, + struct net_device *dev) { struct ip6_tnl *t =3D netdev_priv(dev); + enum skb_drop_reason reason; int encap_limit =3D -1; struct flowi6 fl6; __u8 dsfield =3D 0; @@ -807,54 +809,56 @@ static inline int ip6gre_xmit_ipv4(struct sk_buff *sk= b, struct net_device *dev) err =3D gre_handle_offloads(skb, test_bit(IP_TUNNEL_CSUM_BIT, t->parms.o_flags)); if (err) - return -1; + return SKB_DROP_REASON_NOMEM; =20 - err =3D __gre6_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu, - skb->protocol); - if (err !=3D 0) { + reason =3D __gre6_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu, + skb->protocol); + if (reason) { /* XXX: send ICMP error even if DF is not set. */ - if (err =3D=3D -EMSGSIZE) + if (reason =3D=3D SKB_DROP_REASON_PKT_TOO_BIG) icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu)); - return -1; + return reason; } =20 - return 0; + return SKB_NOT_DROPPED_YET; } =20 -static inline int ip6gre_xmit_ipv6(struct sk_buff *skb, struct net_device = *dev) +static inline enum skb_drop_reason ip6gre_xmit_ipv6(struct sk_buff *skb, + struct net_device *dev) { struct ip6_tnl *t =3D netdev_priv(dev); struct ipv6hdr *ipv6h =3D ipv6_hdr(skb); + enum skb_drop_reason reason; int encap_limit =3D -1; struct flowi6 fl6; __u8 dsfield =3D 0; __u32 mtu; - int err; =20 if (ipv6_addr_equal(&t->parms.raddr, &ipv6h->saddr)) - return -1; + return SKB_DROP_REASON_RECURSION_LIMIT; =20 if (!t->parms.collect_md && prepare_ip6gre_xmit_ipv6(skb, dev, &fl6, &dsfield, &encap_limit)) - return -1; + return SKB_DROP_REASON_IPV6_BAD_EXTHDR; =20 if (gre_handle_offloads(skb, test_bit(IP_TUNNEL_CSUM_BIT, t->parms.o_flags))) - return -1; + return SKB_DROP_REASON_NOMEM; =20 - err =3D __gre6_xmit(skb, dev, dsfield, &fl6, encap_limit, - &mtu, skb->protocol); - if (err !=3D 0) { - if (err =3D=3D -EMSGSIZE) + reason =3D __gre6_xmit(skb, dev, dsfield, &fl6, encap_limit, + &mtu, skb->protocol); + if (reason) { + if (reason =3D=3D SKB_DROP_REASON_PKT_TOO_BIG) icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); - return -1; + return reason; } =20 - return 0; + return SKB_NOT_DROPPED_YET; } =20 -static int ip6gre_xmit_other(struct sk_buff *skb, struct net_device *dev) +static enum skb_drop_reason ip6gre_xmit_other(struct sk_buff *skb, + struct net_device *dev) { struct ip6_tnl *t =3D netdev_priv(dev); int encap_limit =3D -1; @@ -870,25 +874,28 @@ static int ip6gre_xmit_other(struct sk_buff *skb, str= uct net_device *dev) err =3D gre_handle_offloads(skb, test_bit(IP_TUNNEL_CSUM_BIT, t->parms.o_flags)); if (err) - return err; - err =3D __gre6_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu, skb->prot= ocol); + return SKB_DROP_REASON_NOMEM; =20 - return err; + return __gre6_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu, + skb->protocol); } =20 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); @@ -896,17 +903,17 @@ 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); + reason =3D ip6gre_xmit_ipv4(skb, dev); break; case htons(ETH_P_IPV6): - ret =3D ip6gre_xmit_ipv6(skb, dev); + reason =3D ip6gre_xmit_ipv6(skb, dev); break; default: - ret =3D ip6gre_xmit_other(skb, dev); + reason =3D ip6gre_xmit_other(skb, dev); break; } =20 - if (ret < 0) + if (reason) goto tx_err; =20 return NETDEV_TX_OK; @@ -915,13 +922,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); @@ -930,23 +938,29 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_bu= ff *skb, int encap_limit =3D -1; __u8 dsfield =3D false; struct flowi6 fl6; - int err =3D -EINVAL; __be16 proto; __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 @@ -966,8 +980,10 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buf= f *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 @@ -981,8 +997,10 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buf= f *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)); @@ -994,10 +1012,14 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_b= uff *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); @@ -1015,6 +1037,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 { @@ -1025,11 +1048,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)); @@ -1048,6 +1076,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 @@ -1065,11 +1094,11 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_= buff *skb, if (dst_mtu(dst) > mtu) dst->ops->update_pmtu(dst, NULL, skb, mtu, false); } - err =3D ip6_tnl_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu, - NEXTHDR_GRE); - if (err !=3D 0) { + reason =3D ip6_tnl_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu, + NEXTHDR_GRE); + if (reason) { /* XXX: send ICMP error even if DF is not set. */ - if (err =3D=3D -EMSGSIZE) { + if (reason =3D=3D SKB_DROP_REASON_PKT_TOO_BIG) { if (skb->protocol =3D=3D htons(ETH_P_IP)) icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu)); @@ -1085,7 +1114,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..77400a1087af 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -1103,14 +1103,14 @@ EXPORT_SYMBOL_GPL(ip6_tnl_xmit_ctl); * it. * * Return: - * 0 on success - * -1 fail - * %-EMSGSIZE message too big. return mtu in this case. + * %SKB_NOT_DROPPED_YET on success, otherwise the drop reason. + * %SKB_DROP_REASON_PKT_TOO_BIG means the message is too big, the path M= TU + * is stored in @pmtu in this case. **/ =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) +enum skb_drop_reason +ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, + struct flowi6 *fl6, int encap_limit, __u32 *pmtu, __u8 proto) { struct ip6_tnl *t =3D netdev_priv(dev); struct net *net =3D t->net; @@ -1121,11 +1121,11 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_de= vice *dev, __u8 dsfield, int err_count, mtu; unsigned int eth_hlen =3D t->dev->type =3D=3D ARPHRD_ETHER ? ETH_HLEN : 0; unsigned int psh_hlen =3D sizeof(struct ipv6hdr) + t->encap_hlen; + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; unsigned int max_headroom =3D psh_hlen; __be16 payload_protocol; bool use_cache =3D false; u8 hop_limit; - int err =3D -1; =20 payload_protocol =3D skb_protocol(skb, true); =20 @@ -1143,13 +1143,17 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_de= vice *dev, __u8 dsfield, struct neighbour *neigh; int addr_type; =20 - if (!skb_dst(skb)) + if (!skb_dst(skb)) { + reason =3D SKB_DROP_REASON_NO_TX_TARGET; goto tx_err_link_failure; + } =20 neigh =3D dst_neigh_lookup(skb_dst(skb), &ipv6_hdr(skb)->daddr); - if (!neigh) + if (!neigh) { + reason =3D SKB_DROP_REASON_NEIGH_CREATEFAIL; goto tx_err_link_failure; + } =20 addr6 =3D (struct in6_addr *)&neigh->primary_key; addr_type =3D ipv6_addr_type(addr6); @@ -1162,8 +1166,10 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_dev= ice *dev, __u8 dsfield, } else if (payload_protocol =3D=3D htons(ETH_P_IP)) { const struct rtable *rt =3D skb_rtable(skb); =20 - if (!rt) + if (!rt) { + reason =3D SKB_DROP_REASON_NO_TX_TARGET; goto tx_err_link_failure; + } =20 if (rt->rt_gw_family =3D=3D AF_INET6) memcpy(&fl6->daddr, &rt->rt_gw6, sizeof(fl6->daddr)); @@ -1180,8 +1186,10 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_dev= ice *dev, __u8 dsfield, if (use_cache) dst =3D dst_cache_get(&t->dst_cache); =20 - if (!ip6_tnl_xmit_ctl(t, &fl6->saddr, &fl6->daddr)) + if (!ip6_tnl_xmit_ctl(t, &fl6->saddr, &fl6->daddr)) { + reason =3D SKB_DROP_REASON_DEV_READY; goto tx_err_link_failure; + } =20 if (!dst) { route_lookup: @@ -1190,18 +1198,22 @@ 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_IP_OUTNOROUTES; goto tx_err_link_failure; + } ndst =3D dst; } =20 @@ -1211,6 +1223,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; @@ -1224,7 +1237,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_devi= ce *dev, __u8 dsfield, skb_dst_update_pmtu_no_confirm(skb, mtu); 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 +1260,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); @@ -1275,9 +1292,8 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_devi= ce *dev, __u8 dsfield, + dst->header_len + t->hlen; ip_tunnel_adj_headroom(dev, max_headroom); =20 - err =3D ip6_tnl_encap(skb, t, &proto, fl6); - if (err) - return err; + if (ip6_tnl_encap(skb, t, &proto, fl6)) + return SKB_DROP_REASON_TNL_ENCAP; =20 if (encap_limit >=3D 0) { init_tel_txopt(&opt, encap_limit); @@ -1294,21 +1310,22 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_de= vice *dev, __u8 dsfield, ipv6h->saddr =3D fl6->saddr; ipv6h->daddr =3D fl6->daddr; ip6tunnel_xmit(NULL, skb, dev, 0); - return 0; + return SKB_NOT_DROPPED_YET; tx_err_link_failure: DEV_STATS_INC(dev, tx_carrier_errors); dst_link_failure(skb); tx_err_dst_release: dst_release(dst); - return err; + return reason; } EXPORT_SYMBOL(ip6_tnl_xmit); =20 -static inline int +static inline enum skb_drop_reason ipxip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, u8 protocol) { struct ip6_tnl *t =3D netdev_priv(dev); + enum skb_drop_reason reason; struct ipv6hdr *ipv6h; const struct iphdr *iph; int encap_limit =3D -1; @@ -1317,11 +1334,10 @@ ipxip6_tnl_xmit(struct sk_buff *skb, struct net_dev= ice *dev, __u8 dsfield, orig_dsfield; __u32 mtu; u8 tproto; - int err; =20 tproto =3D READ_ONCE(t->parms.proto); if (tproto !=3D protocol && tproto !=3D 0) - return -1; + return SKB_DROP_REASON_UNHANDLED_PROTO; =20 if (t->parms.collect_md) { struct ip_tunnel_info *tun_info; @@ -1330,7 +1346,7 @@ ipxip6_tnl_xmit(struct sk_buff *skb, struct net_devic= e *dev, 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)) - return -1; + return SKB_DROP_REASON_TUNNEL_TXINFO; key =3D &tun_info->key; memset(&fl6, 0, sizeof(fl6)); fl6.flowi6_proto =3D protocol; @@ -1367,7 +1383,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); - return -1; + return SKB_DROP_REASON_IPV6_BAD_EXTHDR; } encap_limit =3D tel->encap_limit - 1; } @@ -1409,15 +1425,15 @@ ipxip6_tnl_xmit(struct sk_buff *skb, struct net_dev= ice *dev, dsfield =3D INET_ECN_encapsulate(dsfield, orig_dsfield); =20 if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6)) - return -1; + return SKB_DROP_REASON_NOMEM; =20 skb_set_inner_ipproto(skb, protocol); =20 - err =3D ip6_tnl_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu, - protocol); - if (err !=3D 0) { + reason =3D ip6_tnl_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu, + protocol); + if (reason) { /* XXX: send ICMP error even if DF is not set. */ - if (err =3D=3D -EMSGSIZE) + if (reason =3D=3D SKB_DROP_REASON_PKT_TOO_BIG) switch (protocol) { case IPPROTO_IPIP: icmp_ndo_send(skb, ICMP_DEST_UNREACH, @@ -1429,20 +1445,21 @@ ipxip6_tnl_xmit(struct sk_buff *skb, struct net_dev= ice *dev, default: break; } - return -1; + return reason; } =20 - return 0; + return SKB_NOT_DROPPED_YET; } =20 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,19 +1467,22 @@ 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); - if (ret < 0) + reason =3D ipxip6_tnl_xmit(skb, dev, ipproto); + if (reason) goto tx_err; =20 return NETDEV_TX_OK; @@ -1470,7 +1490,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