From nobody Fri Sep 25 04:38:26 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 B5E3E51990B for ; Wed, 16 Sep 2026 14:37:28 +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=1789569450; cv=none; b=hWgV0YIMoNdb8G7q9GCrZov9+Yeb1oQq90hESeUwaSZp4eiEX8MufTs92hi+RDa+vssSzPre4H1oqAzXNioqIJud9HqrEXMeGbvb6XMa6XOZHqFWwDYSTIPEVzePA7xPI4PndcR5v7KotE9HGhdb0nAkJv5j8VDeRriNuycvdzI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789569450; c=relaxed/simple; bh=59WxsqcOX2L2RBvv5RmjuUVbgHr8/VHIhI1MMHeZfPM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PlcAE86lQj9Bmoc2fXyJYRjSmjSh2/67Whg3+gtw6iqCSM0IJuNAuvj4VoQAWCmxSjjeSNsjAjyPVT16/AwXSBB37Mv+cvu8Ky3pcYrzlflSppP7N05124PeocBq+/E5G8/cFxx/hFoEKrhx3RJU5bh7pUlRMcoCEtXfQowjxd0= 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=EgQVA3Ad; 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="EgQVA3Ad" Received: by mail-lf2-f13.google.com with SMTP id 2adb3069b0e04-5b7be8dbabfso956458e87.2 for ; Wed, 16 Sep 2026 07:37:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789569447; x=1790174247; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=DAfpRG4RgjzEpNA/SBmwyiTwL7l/5J9GMQEmcjE9tJM=; b=EgQVA3Ad0Ebu5E3smlu8xfxqxy9bgv+uIBiUx86MUk7dJrOorcnzmn/Sa+WPScxO+H X0M4oHOOLYBFQCvaBivLhSUqYWprjDrRkwcXicU8PD+E4MTafFV6D736hke/Q30n2mlr eCQOm6TjURXHIq9TrVx2XzlJjEew/vCGbZxm9Jw+fDzHavgNIhH7y0jxHPU8Z/r9E9dE hIIuClV2vF8i5jzTdjNjzF3rH1LA+nNZTMSsM4qqR1CLWt35KHEUZ5kgqlGa5Lhf2rQZ sP2SF7IsEjdjwTwxSS3qn+daWNsIfMenGqcTz47x/M+WLFmxBYe2faBLn34qXA5E7Zkr bXRw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789569447; x=1790174247; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=DAfpRG4RgjzEpNA/SBmwyiTwL7l/5J9GMQEmcjE9tJM=; b=EPQaojqbxCF00Vc2KjLf/qWh9f1uPlhF2SiXAhGcE6vN+5UwR6A1ia7AdlNsPgUPoJ 4hUspCa1OiiZG3ljHIoK81gVwY1vn5RpbR5xQ2QH7YmOsNkILeqbJRthJHNneeyqnNVZ 48hZjpY+GMFP1I6jDlbI827+l259YHP+yX/iaU5fHRKjDydfZI1pVX3pdHMNmilkCQ2c WMbaGL2z0kE7KQfQbK0YO0//b/ZUPXPJoWsi5U6aYl4o/SMsLxP8JdJTOL3uyfh28a3O T4j6KhG6RkiNwYMw+OCL/N6tEiakr418FoVBRxpGFiCDTyrtjIkSPA6qYcIRA2VlrO4j bSjw== X-Forwarded-Encrypted: i=1; AKwUvBzT5FGwQC0YjYzDQkpZQx+VX8LkMvf3KbeBuJmKndM8kkUWcQB2dQi0jczV+F9x0YWBcqMj0ZMwFroKXEY=@vger.kernel.org X-Gm-Message-State: AFuF++nDRfruVDqeCSuHlaazcGTXvRJKe1PsJF+4xagrztyxfmVvPHYp ewafQwQa+jvqRw+Tpbz6L1RgLgJq+kIoUOJBzSDoKXRCqObVoNz//web X-Gm-Gg: AYBFou1zLB1x8tIiKIzkxcRfMtYgUf7lLP9SzqLx0sbJXmt4lpJ9tl2uJ/i7Y9fP3HT 27M0TnPkwnsAPtv57jFpCKotXo/ASGBw/tyAeLeCQKfLt8lXgQxhFpub+/nj2X3UfQCQ33Ug5bZ NLUpUfql0gJNQlBtCT00n+Vp1TRvIcxh44kHyAZWRWF2O8Sc8vVjhLTZCqcXZ1rEEiSiSQHqMI9 HokPPNfYPWKJlMESO0eTqqzgtDwtL4qrgJWalWWXDNKk/2kw8b1UzHU0fy04hDwpeBaBC+0Eiki IRTclwNLQIyPdVgjNglZxIfPs0SGMfE4Ihfbj7FXi8dfwYs2VwLrJL4RNsbWBXcTsF8+ZKkq3sX tsjmCZisHSq461jMKxoN1olXu4zwwUuaLr5m9t6vhiEjcJpf4CE2PsEMMEM+TQeAG0RLQJN/ba8 jv+eh1R+ZSHXRBBPc8Jtf3gijSNqzYVjD/lMBY/HJtHacHGnQWRR7x/EzCoFAq7FN7yIcCVNYt/ 3v0e7MKaDj7XG+dRqOG4efcuvD2Yg9C8BfFyWEUosNDst/AbXsFFr3Pi2SX4U8y X-Received: by 2002:a05:6512:3b1e:b0:5ae:b2b0:4c0e with SMTP id 2adb3069b0e04-5b8b661230amr903694e87.1.1789569446400; Wed, 16 Sep 2026 07:37:26 -0700 (PDT) Received: from dau-home-pc.megasoftware.org ([95.139.134.117]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b8b57eb908sm955658e87.79.2026.09.16.07.37.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Sep 2026 07:37: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 v3 1/9] ip_tunnel: add drop reasons to the generic RX path Date: Wed, 16 Sep 2026 17:37:09 +0300 Message-ID: <20260916143717.1875082-2-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260916143717.1875082-1-littlesmilingcloud@gmail.com> References: <20260916143717.1875082-1-littlesmilingcloud@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" ip_tunnel_rcv() collapses four distinct failures into a single plain kfree_skb(), so a packet dropped there simply vanishes: - the tunnel options carried by the packet do not match the tunnel configuration (checksum or sequence number), - the sequence number is older than the expected one, - the inner network header cannot be pulled, - the ECN decapsulation check fails (RFC 6040). Only the device error counters (rx_crc_errors, rx_fifo_errors, rx_length_errors, rx_frame_errors) hint at the cause, and they are not reported to drop_monitor or to the skb:kfree_skb tracepoint. Add two drop reasons for the tunnel specific cases and reuse the existing ones for the rest: - SKB_DROP_REASON_TNL_OPT_MISMATCH is used when the packet does not carry the checksum or the sequence number option the tunnel is configured for. This is a configuration mismatch between the two endpoints rather than a corrupted checksum: the checksum itself is validated earlier, in gre_parse_header(). - SKB_DROP_REASON_TNL_OLD_SEQ is used when the sequence number is older than the expected one. Unlike the previous one this is a property of the received traffic: a remote endpoint that restarts and resets its sequence numbering has all of its packets dropped until i_seqno catches up. - pskb_inet_may_pull_reason() already computes a drop reason, SKB_DROP_REASON_PKT_TOO_SMALL or SKB_DROP_REASON_NOMEM, which was discarded so far. - SKB_DROP_REASON_IP_TUNNEL_ECN already exists and documents exactly this check, but until now it was only used by vxlan. The sequence number test is split in two so that the two cases can be told apart. The error counters are left unchanged. ip_tunnel_rcv() is the RX path of ip_gre, ipip and sit. The checksum and the sequence number options only exist for GRE, so the two new reasons are reachable through ip_gre alone, while the length and the ECN ones apply to all three. Assisted-by: Claude-Code:claude-opus-5 Signed-off-by: Anton Danilov --- include/net/dropreason-core.h | 16 ++++++++++++++++ net/ipv4/ip_tunnel.c | 19 +++++++++++++++---- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/include/net/dropreason-core.h b/include/net/dropreason-core.h index 12f909651591..e1fdd11c939f 100644 --- a/include/net/dropreason-core.h +++ b/include/net/dropreason-core.h @@ -129,6 +129,8 @@ FN(PSP_INPUT) \ FN(PSP_OUTPUT) \ FN(RECURSION_LIMIT) \ + FN(TNL_OPT_MISMATCH) \ + FN(TNL_OLD_SEQ) \ FNe(MAX) =20 /** @@ -612,6 +614,20 @@ enum skb_drop_reason { SKB_DROP_REASON_PSP_OUTPUT, /** @SKB_DROP_REASON_RECURSION_LIMIT: Dead loop on virtual device. */ SKB_DROP_REASON_RECURSION_LIMIT, + /** + * @SKB_DROP_REASON_TNL_OPT_MISMATCH: the tunnel options + * carried by the packet do not match the tunnel configuration, e.g. + * a GRE tunnel configured with 'icsum' or 'iseq' received a packet + * with no checksum or no sequence number. + */ + SKB_DROP_REASON_TNL_OPT_MISMATCH, + /** + * @SKB_DROP_REASON_TNL_OLD_SEQ: the sequence number carried + * by the packet is older than the one expected by the tunnel, e.g. + * after the remote endpoint restarted and reset its sequence + * numbering. + */ + SKB_DROP_REASON_TNL_OLD_SEQ, /** * @SKB_DROP_REASON_MAX: the maximum of core drop reasons, which * shouldn't be used as a real 'reason' - only for tracing code gen diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index 13b5e35e8790..0260a97e990e 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -378,6 +378,7 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_b= uff *skb, const struct tnl_ptk_info *tpi, struct metadata_dst *tun_dst, bool log_ecn_error) { + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; const struct iphdr *iph =3D ip_hdr(skb); int nh, err; =20 @@ -392,14 +393,22 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk= _buff *skb, test_bit(IP_TUNNEL_CSUM_BIT, tpi->flags)) { DEV_STATS_INC(tunnel->dev, rx_crc_errors); DEV_STATS_INC(tunnel->dev, rx_errors); + reason =3D SKB_DROP_REASON_TNL_OPT_MISMATCH; goto drop; } =20 if (test_bit(IP_TUNNEL_SEQ_BIT, tunnel->parms.i_flags)) { - if (!test_bit(IP_TUNNEL_SEQ_BIT, tpi->flags) || - (tunnel->i_seqno && (s32)(ntohl(tpi->seq) - tunnel->i_seqno) < 0)) { + if (!test_bit(IP_TUNNEL_SEQ_BIT, tpi->flags)) { DEV_STATS_INC(tunnel->dev, rx_fifo_errors); DEV_STATS_INC(tunnel->dev, rx_errors); + reason =3D SKB_DROP_REASON_TNL_OPT_MISMATCH; + goto drop; + } + if (tunnel->i_seqno && + (s32)(ntohl(tpi->seq) - tunnel->i_seqno) < 0) { + DEV_STATS_INC(tunnel->dev, rx_fifo_errors); + DEV_STATS_INC(tunnel->dev, rx_errors); + reason =3D SKB_DROP_REASON_TNL_OLD_SEQ; goto drop; } tunnel->i_seqno =3D ntohl(tpi->seq) + 1; @@ -413,7 +422,8 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_b= uff *skb, =20 skb_set_network_header(skb, (tunnel->dev->type =3D=3D ARPHRD_ETHER) ? ETH= _HLEN : 0); =20 - if (!pskb_inet_may_pull(skb)) { + reason =3D pskb_inet_may_pull_reason(skb); + if (reason) { DEV_STATS_INC(tunnel->dev, rx_length_errors); DEV_STATS_INC(tunnel->dev, rx_errors); goto drop; @@ -428,6 +438,7 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_b= uff *skb, if (err > 1) { DEV_STATS_INC(tunnel->dev, rx_frame_errors); DEV_STATS_INC(tunnel->dev, rx_errors); + reason =3D SKB_DROP_REASON_IP_TUNNEL_ECN; goto drop; } } @@ -451,7 +462,7 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_b= uff *skb, drop: if (tun_dst) dst_release((struct dst_entry *)tun_dst); - kfree_skb(skb); + kfree_skb_reason(skb, reason); return 0; } EXPORT_SYMBOL_GPL(ip_tunnel_rcv); --=20 2.47.3 From nobody Fri Sep 25 04:38:26 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 BA75A51118D for ; Wed, 16 Sep 2026 14:37:29 +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=1789569451; cv=none; b=tbFzdLa618bPA8cQSgfYrup194d2l8oV5Ybq8cFqwG7fbmIBal0xnYHR3pSburPCLyxeHrwohyL/b2yL3SmKOicGCI2Ior4vr+JPhB5RIhHCtXovcSAluC0lRQXUdrSGluhbmzJf+RmYKjJCZdqiUnXr3UK85LzbWxQo4kLdzSc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789569451; c=relaxed/simple; bh=IygfgVwXatJFE+RkNcAXu7MXWyMXCZoruPbUZw0iC9o=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kEz+nWhIznHNlMTiPBk4qP5qzF2xk55JpNir+43y/R8Em5fKB18t31Q6Gi77Cj8cPp4mWii1g7IX/tZeb/SafTKD8vHkhhf3v+iarq7yXxKOpw8BZhZh1CFhK8CnZTOAe96LSYg5ICWtDayBYN59hIFzaTG4LhqcFg7/2z4swWM= 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=JBwZiAb1; 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="JBwZiAb1" Received: by mail-lf2-f13.google.com with SMTP id 2adb3069b0e04-5b5e4f1744eso953119e87.1 for ; Wed, 16 Sep 2026 07:37:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789569448; x=1790174248; 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=M6M76N+fUjJdrgvQgsP7ki/1dRlq0jIuyTjFozFcAyE=; b=JBwZiAb1ieOqFMvGx4yDcRQKiILKM4ppU85fNZWfYQi9nC4E1FxSA8RBThRr3DcmC6 s8+YurnmYPYWG1vssfcVDaeqolWcwvnO+vBKC0Zo+YUKJ1BLUYfQsvmMkeO3caIZ2FE3 6TAJ3KnK4Rw2vYU+1IGlniywAwiRHkOHnicMHwqLFoGKN6RSWRhxsEvWD9L3U5u1X6Ar AGSXfKHxH+6dzUxDPxSUDp5CpsPyCC3cJXAQbeH2lZpEkIyb0LP9K/8x8YqHjQ6WohkO 1AECqMlcAzucCNQpbOA1cn3wTJX3rLwpIrHLvwaA2d0xfANgCcRefGjqti+xGCbLX578 OkJQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789569448; x=1790174248; 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=M6M76N+fUjJdrgvQgsP7ki/1dRlq0jIuyTjFozFcAyE=; b=ICGFnIxzKFxFvtgx5FSA/lKWmBfhUGLIteKmWCZr4XpsjRdzZ37LSn2mxYqVCHntMA wYgvrzWhihANoKAUoMLdc05KwTniny0ApoKWNq3vNZ1BcFdI03uNfs3WE/G7m8KWmJ3H 6szT8/A1CH+ZQ19O2jYtw7x2CgxnUYc70uQIGa3u6lldFGvTDK8CScj4kITfBpYLauij ATcII8RI2JvlLfQtVphXZ6qgWkAgccAdGjUJGEF9bROEvwVjc1d/2QLkQDMoGfJysRbF dYhd8MsbXPhJZlbwTuHMEmW4WEkZcogPpGqtl99FXrVhdzR/AD3tIpwoxwUDPHVeoix+ XKnw== X-Forwarded-Encrypted: i=1; AKwUvByop0h3BEZqjxm6s/Lw9hD9qc1ckUOk+4V5v4t1GAnOo0VOtdDRU1jYSZTNgfSggn6vRRn7FqoN9Td6eH4=@vger.kernel.org X-Gm-Message-State: AFuF++l9HAr37qDZr/hGPLStSly5Ntj/lfAXR2OEsNdWShQfvntS73g1 pxMC4B7yNA33i+K3V74sMhFe8x4DK+jdAO5GZK+o/zcMdvms7Ch26pvI X-Gm-Gg: AYBFou2w+4WvaW8lAC3aQj2qkgEY8id2VQCTvKfUkaB01DWj8qbBJfP/c3sOaqUAWAL lQYf9SPyh20qWmXvnz8kkdq2UCnqF/S4MjzjYSj3haoIDxtTFRLIMYFTqw+xsavk+UcBpSx7HTq KUPvIzvTkUu7VI0vn91ejv4qy/KY9Cj7RXhtazrRWjj5St2okNxE1/aB0TpoiU+RU9qdRl31SE3 zIZCj5CqY3+RKPmbvvTMHjoqzPE+AjuewPaWD8zLRTWJ8Z/DecL4Enl9GpDrX23I6J31ge/w8Wj 3MGCXwEKvVesn1iETT18JCjUdp/qj35tjOeFXC4Fs8UPHd+nsDMORr45nw+tqwCZHPmdCP4WJiu Lw7+bh4IJ8Nf7e4Cr3/VRLCsvSepH8hsZXKzQEFyQWe6rkVYsQJ+vrnj0GfacHleMW3UlUXv39P zCPnzuPbDOnmJMCsPlkCOKhUU2IzbJFNivSH/f+B/eeO+DXEfVwG9jEkeHx13i37HzXjScBQ8Lg ZbVhFUav4GzPXXNMJsAnRUTsQebSeMNo+k2kIQYRJ8JDe66gNFfpudaVcwvSSk/Pw== X-Received: by 2002:a05:6512:1189:b0:5b6:31c:bb0c with SMTP id 2adb3069b0e04-5b8b660aab8mr914364e87.9.1789569447505; Wed, 16 Sep 2026 07:37:27 -0700 (PDT) Received: from dau-home-pc.megasoftware.org ([95.139.134.117]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b8b57eb908sm955658e87.79.2026.09.16.07.37.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Sep 2026 07:37:26 -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 v3 2/9] ip6_tunnel: add drop reasons to the generic RX path Date: Wed, 16 Sep 2026 17:37:10 +0300 Message-ID: <20260916143717.1875082-3-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260916143717.1875082-1-littlesmilingcloud@gmail.com> References: <20260916143717.1875082-1-littlesmilingcloud@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" __ip6_tnl_rcv() mirrors its IPv4 counterpart: five distinct failures share a single plain kfree_skb(). Reuse the drop reasons introduced for ip_tunnel_rcv() and the ones the length helpers already return. Note that skb_vlan_inet_prepare() returns an enum skb_drop_reason that was simply discarded, and that pskb_may_pull_reason() has been available all along. __ip6_tnl_rcv() is reached two ways: ip6_gre (ip6gre, ip6gretap, erspan) goes through the exported ip6_tnl_rcv(), while the ip6_tunnel encapsulations (ip4ip6, ip6ip6, mplsip6) reach it from ipxip6_rcv(). As on the IPv4 side, only ip6_gre sets the checksum and sequence number bits -- tpi_v4, tpi_v6 and tpi_mpls carry nothing but .proto -- so the option mismatch and the old sequence reasons are reachable through it alone. Assisted-by: Claude-Code:claude-opus-5 Signed-off-by: Anton Danilov --- net/ipv6/ip6_tunnel.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index d5ff50a2ac01..458ce328311b 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -813,6 +813,7 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct= sk_buff *skb, struct sk_buff *skb), bool log_ecn_err) { + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; const struct ipv6hdr *ipv6h; int nh, err; =20 @@ -820,15 +821,22 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, stru= ct sk_buff *skb, test_bit(IP_TUNNEL_CSUM_BIT, tpi->flags)) { DEV_STATS_INC(tunnel->dev, rx_crc_errors); DEV_STATS_INC(tunnel->dev, rx_errors); + reason =3D SKB_DROP_REASON_TNL_OPT_MISMATCH; goto drop; } =20 if (test_bit(IP_TUNNEL_SEQ_BIT, tunnel->parms.i_flags)) { - if (!test_bit(IP_TUNNEL_SEQ_BIT, tpi->flags) || - (tunnel->i_seqno && - (s32)(ntohl(tpi->seq) - tunnel->i_seqno) < 0)) { + if (!test_bit(IP_TUNNEL_SEQ_BIT, tpi->flags)) { DEV_STATS_INC(tunnel->dev, rx_fifo_errors); DEV_STATS_INC(tunnel->dev, rx_errors); + reason =3D SKB_DROP_REASON_TNL_OPT_MISMATCH; + goto drop; + } + if (tunnel->i_seqno && + (s32)(ntohl(tpi->seq) - tunnel->i_seqno) < 0) { + DEV_STATS_INC(tunnel->dev, rx_fifo_errors); + DEV_STATS_INC(tunnel->dev, rx_errors); + reason =3D SKB_DROP_REASON_TNL_OLD_SEQ; goto drop; } tunnel->i_seqno =3D ntohl(tpi->seq) + 1; @@ -838,7 +846,8 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct= sk_buff *skb, =20 /* Warning: All skb pointers will be invalidated! */ if (tunnel->dev->type =3D=3D ARPHRD_ETHER) { - if (!pskb_may_pull(skb, ETH_HLEN)) { + reason =3D pskb_may_pull_reason(skb, ETH_HLEN); + if (reason) { DEV_STATS_INC(tunnel->dev, rx_length_errors); DEV_STATS_INC(tunnel->dev, rx_errors); goto drop; @@ -859,7 +868,8 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct= sk_buff *skb, =20 skb_reset_network_header(skb); =20 - if (skb_vlan_inet_prepare(skb, true)) { + reason =3D skb_vlan_inet_prepare(skb, true); + if (reason) { DEV_STATS_INC(tunnel->dev, rx_length_errors); DEV_STATS_INC(tunnel->dev, rx_errors); goto drop; @@ -881,6 +891,7 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct= sk_buff *skb, if (err > 1) { DEV_STATS_INC(tunnel->dev, rx_frame_errors); DEV_STATS_INC(tunnel->dev, rx_errors); + reason =3D SKB_DROP_REASON_IP_TUNNEL_ECN; goto drop; } } @@ -898,7 +909,7 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct= sk_buff *skb, drop: if (tun_dst) dst_release((struct dst_entry *)tun_dst); - kfree_skb(skb); + kfree_skb_reason(skb, reason); return 0; } =20 --=20 2.47.3 From nobody Fri Sep 25 04:38:26 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 1010851FCCE for ; Wed, 16 Sep 2026 14:37:30 +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=1789569453; cv=none; b=TD5Q7jG5becOKsbMB+FXVzJjMoZiB0waHPbH0B1mXF4No7CBOHaCYSH4TQOTYZHWoaxL36Unh3KttzPt5zdB+k9K1LjRVrwx1xU/QrUKNDrN1GuPDwbL09EoCK2QF0ITQRA4684V9plYHDXGGWhamy+3yOOiPBIASS8BHhW05pU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789569453; c=relaxed/simple; bh=VRzImSPQoUL1+TR5Aq1AzNog5kxGpZLs1ElY9xVdIK8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GqeYzS4KIRJoExBRNk1rO8qctYsgInjpbeZXtQFOoq2bjvydGzkligIE6kSW8djdOgDJvITeCUzE5thWLVZu01mJTfxzaG6PYMJesgHld61/4DdKiD5zZ2AC5PwFScnUZ/ccQVQ0ymxZ4qY36OWLI/brp1+WwfKdAJ7iFascyFc= 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=FkOjbFuI; 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="FkOjbFuI" Received: by mail-lf2-f12.google.com with SMTP id 2adb3069b0e04-5b5e4f17450so932313e87.0 for ; Wed, 16 Sep 2026 07:37:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789569449; x=1790174249; 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=6pnqDmHUn4GuJkxfLfl6U2c0IlVUX25aIG3vt+TH9Zs=; b=FkOjbFuIXMCxBwGJbFfxaTbIuCWM7meFB1JeIujDnUQZAx+xoM1JLYWDSvsM/eGCEg oV8hd9RGdlACBuZEvx3L7JwdeEnQHroVOgwlRKP8NB91x1fAff9WZOVnTALs2fEpBZmD KPTLeqrhz3ZD+eG2jb41a3DfNs1BCbth5KhuvsgNWVFUXHCFbHTDGuexQ7KVvais2jxV tuJ1hMX+dc/hQTORbFc1P96ePdCSKRLEJytJSQaTrTqUdbW8/v1MLFlEw4gZa+2qtyFW wOFMKiUEBd/+NVyfEbvvN0gc9yWeUfepoVBthe5Po0yjjI8FI78hwG1GJK9GLuM5Clzi icQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789569449; x=1790174249; 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=6pnqDmHUn4GuJkxfLfl6U2c0IlVUX25aIG3vt+TH9Zs=; b=PbzZ0C2hfP4JxpsgH9qxpYLzICP+fpQKREGGga2JKjvy/HinzPjeX4WhqFrZ0dU6pQ H8qLAhp1BffsVpVTuP/yZoXl/ROL3NqHd7IbtIv74bFSptJpihjiqWJFhtYnnvAZeEOQ oNoYNyNmBQvig2tUXhYZRKTGPZ0x/HFwOzyNCuZ94c35kWkV26syBbc6pY57LgaYDDYS 3/u1HGVCziFmTDy3e06papoClIp/2m+Yitl+DfqTX8EkwS8daxwW254IoHKKs7sVtVG3 R+F3ro99TAp5T2Sz/Mqb5CCPbtkel7TBXQt/e6TgKdnp8gww8NCPHwh8RGkW/b6lQJhL e7Bg== X-Forwarded-Encrypted: i=1; AKwUvBxwhOb1z4hFZojTcMGSG+r79/5E6JZs1IJKyJnSd0UxXoY6ygJ7P08cXSU61knNIpZB55Ftkg1tK7KG0bI=@vger.kernel.org X-Gm-Message-State: AFuF++ksYxleLp03CvGgGK4uukcIYu4MJjdZ73QNNlBhLLmZZXmM6KS4 uR7nYUVPovtP02XCmauCcywaul2wXV/rYaMoR67+VVkqn3/lmHBrJuIf X-Gm-Gg: AYBFou3YaJ8hdrtdMU0Zd5YnLrHPb8MGzJkKjxuiLU6EALOoKPCcq0dNhHDGwVM4HHX 2AzqzlYvzhnp1iBVoyN1nBZDCgM77KfToLqvJfIW8z5f7ky4D/iy7bxskv8VqxsyEjFNX0hnVM9 bZEOEvxz2O5v4u8XivF01tPozhFuhy+PEjls8eNSFLZPIeTllqt1UcSaklUCas3g3cKB+OFWLJO AWY6Fygm5+QKvWDEW1/DNbtJyXVdEBVgYP5KoMJf8mQL/SXWwVK/VMhV0UxeTxlMsecM3svBs8J tOR3BqdKriZnYt9ulNUVf6gX2Uj2RhqF4aB/Ac2WDjIxVSkfSqr4HjKj22BjVjSpYTlHg/XlZG2 zq+C4eHTWmkeSo+zRLrWB1OtACM/zeZl7N1e59V65/k+Wbkchwr2Nz0Ln1cj9VrHr7gKRBvhqor HERb7aHi57/wTweTx6jNkSRYPcQFBdAq1gv4hbZcH3JIvY2sqgmk6E2UU1UY9TtjtmuazIpKQQ/ T2ZfbDPRFRxaMv6J+UT9MSzy0Ez8oCuRfcyHairKTemo/9sCKIGpsH/W7iieEKS X-Received: by 2002:a05:6512:3da8:b0:5b6:183c:5c8c with SMTP id 2adb3069b0e04-5b8b6645ec3mr998401e87.42.1789569448577; Wed, 16 Sep 2026 07:37:28 -0700 (PDT) Received: from dau-home-pc.megasoftware.org ([95.139.134.117]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b8b57eb908sm955658e87.79.2026.09.16.07.37.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Sep 2026 07:37: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 v3 3/9] gre: make gre_parse_header() report a drop reason Date: Wed, 16 Sep 2026 17:37:11 +0300 Message-ID: <20260916143717.1875082-4-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260916143717.1875082-1-littlesmilingcloud@gmail.com> References: <20260916143717.1875082-1-littlesmilingcloud@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" gre_parse_header() returns -EINVAL for six different reasons and its callers turn that into a plain kfree_skb(). The only detail they could get so far was the csum_err flag, which none of them actually reads: both ip_gre and ip6_gre declare it, pass it in and then ignore it. Replace that dead output parameter with an enum skb_drop_reason one and let the two receive paths report what happened. Two reasons are added: - SKB_DROP_REASON_GRE_INVALID_HDR, for a header carrying an unsupported version or the routing bit, - SKB_DROP_REASON_GRE_CSUM, for a checksum error, next to the existing TCP_CSUM, UDP_CSUM, ICMP_CSUM and IP_CSUM. The header pull failures reuse SKB_DROP_REASON_HDR_TRUNC, which documents exactly this case, and gre_rcv() in the demux reuses pskb_may_pull_reason() and SKB_DROP_REASON_UNHANDLED_PROTO. A NULL reason keeps the meaning a NULL csum_err had: the caller is not interested in it and a checksum failure must not be reported. The checksum is still computed either way, the packet is just not rejected over it. This is what the ICMP error handlers need, as they only get a part of the original packet. Tunnel lookup failures still report SKB_DROP_REASON_NOT_SPECIFIED here; they are addressed in the following patches. Assisted-by: Claude-Code:claude-opus-5 Signed-off-by: Anton Danilov --- include/net/dropreason-core.h | 9 ++++++ include/net/gre.h | 2 +- net/ipv4/gre_demux.c | 52 +++++++++++++++++++++++++++-------- net/ipv4/ip_gre.c | 6 ++-- net/ipv6/ip6_gre.c | 6 ++-- 5 files changed, 56 insertions(+), 19 deletions(-) diff --git a/include/net/dropreason-core.h b/include/net/dropreason-core.h index e1fdd11c939f..6ae7a604722d 100644 --- a/include/net/dropreason-core.h +++ b/include/net/dropreason-core.h @@ -131,6 +131,8 @@ FN(RECURSION_LIMIT) \ FN(TNL_OPT_MISMATCH) \ FN(TNL_OLD_SEQ) \ + FN(GRE_INVALID_HDR) \ + FN(GRE_CSUM) \ FNe(MAX) =20 /** @@ -628,6 +630,13 @@ enum skb_drop_reason { * numbering. */ SKB_DROP_REASON_TNL_OLD_SEQ, + /** + * @SKB_DROP_REASON_GRE_INVALID_HDR: the GRE header is invalid, e.g. + * an unsupported version or the routing bit is set. + */ + SKB_DROP_REASON_GRE_INVALID_HDR, + /** @SKB_DROP_REASON_GRE_CSUM: GRE checksum error */ + SKB_DROP_REASON_GRE_CSUM, /** * @SKB_DROP_REASON_MAX: the maximum of core drop reasons, which * shouldn't be used as a real 'reason' - only for tracing code gen diff --git a/include/net/gre.h b/include/net/gre.h index b55f67ecd2fc..a63f26c3f78e 100644 --- a/include/net/gre.h +++ b/include/net/gre.h @@ -33,7 +33,7 @@ int gre_add_protocol(const struct gre_protocol *proto, u8= version); int gre_del_protocol(const struct gre_protocol *proto, u8 version); =20 int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi, - bool *csum_err, __be16 proto, int nhs); + enum skb_drop_reason *reason, __be16 proto, int nhs); =20 static inline bool netif_is_gretap(const struct net_device *dev) { diff --git a/net/ipv4/gre_demux.c b/net/ipv4/gre_demux.c index 96fd7dc6d82d..c5d3847848ef 100644 --- a/net/ipv4/gre_demux.c +++ b/net/ipv4/gre_demux.c @@ -58,26 +58,44 @@ EXPORT_SYMBOL_GPL(gre_del_protocol); =20 /* Fills in tpi and returns header length to be pulled. * Note that caller must use pskb_may_pull() before pulling GRE header. + * + * @reason is only written when the header is rejected, so the caller has + * to initialise it before the call. + * + * A NULL @reason means that the caller is not interested in the drop + * reason, and also that a checksum failure must not be reported: the + * checksum is still computed, the packet is just not rejected over it. + * This is what the ICMP error handlers need, as they only get a part of + * the original packet. */ int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi, - bool *csum_err, __be16 proto, int nhs) + enum skb_drop_reason *reason, __be16 proto, int nhs) { const struct gre_base_hdr *greh; __be32 *options; int hdr_len; =20 - if (unlikely(!pskb_may_pull(skb, nhs + sizeof(struct gre_base_hdr)))) + if (unlikely(!pskb_may_pull(skb, nhs + sizeof(struct gre_base_hdr)))) { + if (reason) + *reason =3D SKB_DROP_REASON_HDR_TRUNC; return -EINVAL; + } =20 greh =3D (struct gre_base_hdr *)(skb->data + nhs); - if (unlikely(greh->flags & (GRE_VERSION | GRE_ROUTING))) + if (unlikely(greh->flags & (GRE_VERSION | GRE_ROUTING))) { + if (reason) + *reason =3D SKB_DROP_REASON_GRE_INVALID_HDR; return -EINVAL; + } =20 gre_flags_to_tnl_flags(tpi->flags, greh->flags); hdr_len =3D gre_calc_hlen(tpi->flags); =20 - if (!pskb_may_pull(skb, nhs + hdr_len)) + if (!pskb_may_pull(skb, nhs + hdr_len)) { + if (reason) + *reason =3D SKB_DROP_REASON_HDR_TRUNC; return -EINVAL; + } =20 greh =3D (struct gre_base_hdr *)(skb->data + nhs); tpi->proto =3D greh->protocol; @@ -87,8 +105,8 @@ int gre_parse_header(struct sk_buff *skb, struct tnl_ptk= _info *tpi, if (!skb_checksum_simple_validate(skb)) { skb_checksum_try_convert(skb, IPPROTO_GRE, null_compute_pseudo); - } else if (csum_err) { - *csum_err =3D true; + } else if (reason) { + *reason =3D SKB_DROP_REASON_GRE_CSUM; return -EINVAL; } =20 @@ -116,8 +134,11 @@ int gre_parse_header(struct sk_buff *skb, struct tnl_p= tk_info *tpi, =20 val =3D skb_header_pointer(skb, nhs + hdr_len, sizeof(_val), &_val); - if (!val) + if (!val) { + if (reason) + *reason =3D SKB_DROP_REASON_HDR_TRUNC; return -EINVAL; + } tpi->proto =3D proto; if ((*val & 0xF0) !=3D 0x40) hdr_len +=3D 4; @@ -132,8 +153,11 @@ int gre_parse_header(struct sk_buff *skb, struct tnl_p= tk_info *tpi, greh->protocol =3D=3D htons(ETH_P_ERSPAN2)) { struct erspan_base_hdr *ershdr; =20 - if (!pskb_may_pull(skb, nhs + hdr_len + sizeof(*ershdr))) + if (!pskb_may_pull(skb, nhs + hdr_len + sizeof(*ershdr))) { + if (reason) + *reason =3D SKB_DROP_REASON_HDR_TRUNC; return -EINVAL; + } =20 ershdr =3D (struct erspan_base_hdr *)(skb->data + nhs + hdr_len); tpi->key =3D cpu_to_be32(get_session_id(ershdr)); @@ -145,16 +169,20 @@ EXPORT_SYMBOL(gre_parse_header); =20 static int gre_rcv(struct sk_buff *skb) { + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; const struct gre_protocol *proto; u8 ver; int ret; =20 - if (!pskb_may_pull(skb, 12)) + reason =3D pskb_may_pull_reason(skb, 12); + if (reason) goto drop; =20 ver =3D skb->data[1]&0x7f; - if (ver >=3D GREPROTO_MAX) + if (ver >=3D GREPROTO_MAX) { + reason =3D SKB_DROP_REASON_UNHANDLED_PROTO; goto drop; + } =20 rcu_read_lock(); proto =3D rcu_dereference(gre_proto[ver]); @@ -167,11 +195,11 @@ static int gre_rcv(struct sk_buff *skb) drop_nohandler: rcu_read_unlock(); dev_core_stats_rx_nohandler_inc(skb->dev); - kfree_skb(skb); + kfree_skb_reason(skb, SKB_DROP_REASON_UNHANDLED_PROTO); return NET_RX_DROP; drop: dev_core_stats_rx_dropped_inc(skb->dev); - kfree_skb(skb); + kfree_skb_reason(skb, reason); return NET_RX_DROP; } =20 diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 82309efd417e..1894c5746a73 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -439,8 +439,8 @@ static int ipgre_rcv(struct sk_buff *skb, const struct = tnl_ptk_info *tpi, =20 static int gre_rcv(struct sk_buff *skb) { + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; struct tnl_ptk_info tpi; - bool csum_err =3D false; int hdr_len; =20 #ifdef CONFIG_NET_IPGRE_BROADCAST @@ -451,7 +451,7 @@ static int gre_rcv(struct sk_buff *skb) } #endif =20 - hdr_len =3D gre_parse_header(skb, &tpi, &csum_err, htons(ETH_P_IP), 0); + hdr_len =3D gre_parse_header(skb, &tpi, &reason, htons(ETH_P_IP), 0); if (hdr_len < 0) goto drop; =20 @@ -469,7 +469,7 @@ static int gre_rcv(struct sk_buff *skb) icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); drop: dev_core_stats_rx_dropped_inc(skb->dev); - kfree_skb(skb); + kfree_skb_reason(skb, reason); return 0; } =20 diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 8ebda0b6a78b..78854cc2dac9 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -569,11 +569,11 @@ static int ip6erspan_rcv(struct sk_buff *skb, =20 static int gre_rcv(struct sk_buff *skb) { + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; struct tnl_ptk_info tpi; - bool csum_err =3D false; int hdr_len; =20 - hdr_len =3D gre_parse_header(skb, &tpi, &csum_err, htons(ETH_P_IPV6), 0); + hdr_len =3D gre_parse_header(skb, &tpi, &reason, htons(ETH_P_IPV6), 0); if (hdr_len < 0) goto drop; =20 @@ -594,7 +594,7 @@ static int gre_rcv(struct sk_buff *skb) icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0); drop: dev_core_stats_rx_dropped_inc(skb->dev); - kfree_skb(skb); + kfree_skb_reason(skb, reason); return 0; } =20 --=20 2.47.3 From nobody Fri Sep 25 04:38:26 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 036DC5221C8 for ; Wed, 16 Sep 2026 14:37:31 +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=1789569454; cv=none; b=h4JbHoSYhXCp7lgzjyreON1exJ7gVN/dkXSKWac6f/IgwGKR+1QS5bXiNKLFXDWml+ihP7MciGw9TsruFD3KbZ9EHq4dO+jTDhapoxo8MoEzm26XZSMeaXkGRSIQAiFGa/6NIJ4xZghQatFNMKrc2kGjmLOS5i8CSwwpGZ0F3X8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789569454; c=relaxed/simple; bh=TL5RDsgR3q3rNoxaBtuxVQUD5JBfU63nw915qZTE9T4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=k6jGjXeCRDsdiDY0+R2Q257yAZ3KrYfgwj5FF22Z3fyb7wmPZElq0XWayFP6IwTdBT5KiTBxdLQK7YGs7CGGrNb7JY+AHHzofROKH5veKdQQB3hsNIQ3HInot8HTFaSIQA6lAr2POof9y2pypmV/LyOG9vk5oHm8osQbnKelh6Q= 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=LlrjGE2k; 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="LlrjGE2k" Received: by mail-lf2-f12.google.com with SMTP id 2adb3069b0e04-5b5e4f15b79so986878e87.1 for ; Wed, 16 Sep 2026 07:37:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789569450; x=1790174250; 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=49hTZf7QlRMaCxSNEmZ3eVg+9HKmB4MI7noIxZyhpu0=; b=LlrjGE2k9yVazxoxmkkl8uLeF3f/3ZB0pseTJTNSwsWbUSozM9yEIWXW7SeJIaFHkw y63a4gcMgzlFWLZP9eN5dMujdMFz9ePLvHEH8IVXF/3GzZ70qqIuMJoh9XMYmppugMKI 1o+QHmaN57xhZbJ8fYbtJtdJLQ9b4cTuDf3iqBwKe7cCmluHokiUT0ne0gFB3kMrEIjk DEBKk8aIJPnO2xd7/VUNfAn2Wyf5/xsJl4PNKBYQCTS8PPyHfGAR7X1/qwCW0AIG2iKC ANcCPbFiTvonCmeVwCNHwg0qdaAmz+3qloT/wZf+M0em/iIDoDcIOpplROW085NycWPg 20SA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789569450; x=1790174250; 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=49hTZf7QlRMaCxSNEmZ3eVg+9HKmB4MI7noIxZyhpu0=; b=Vai2cPSLjxPk5bMdwpVzuKHA4dtkp1vcwtUwSMyi3uI2U5Ttx8INp1zIkkqAnb9jwX u5toJX4dNQrWCNXiyG+GEpLEfHZ71UTepM3kJ01QwoVkU3AKBqrc6wuI5YrszGHnifnK P4nPK0xNFAhOR71h2lxU7Mfq3yVPHbAOVJCYPkgq5FJJUk5X2tVlh4oWlbXOXc3R/jgl BLh11s2h9p0IkLoM/sMVMI8VJorJnGAse7/HtA/AfoA2c7YxwiKGlxowcmiGNr+Dc6u3 Z67GQ/do4pIq4FhP/I/m5WKxSIXzrQn/zhP4D2NcVSctXcCC3B8DZP5sPOdH9MtiwCXY FpAA== X-Forwarded-Encrypted: i=1; AKwUvBwYXFHDVESnfpT9if8pAkVxF+FCgMGXrola9z3EXQoYMLL2Gc1PDTEIqojVwjWZLJpZ3jzqNlNISn8Ofrg=@vger.kernel.org X-Gm-Message-State: AFuF++nlCYnM1TQSpVBhR14CtL8Yu7TxwkPmLfRngQGMrPAdr7ReMyDp 4BkrNchV654eD8ugnmxmX8ayhHNkq2+c7z4VefQzHaazS09viOSKe7R2 X-Gm-Gg: AYBFou20ygcd7Guki1QSUs3A4u+bEHUrkHqZKhhYlUW8QhPtGpFaJ3Cfejj5OqvGUzg E5jyS/QuZucabX1UCTfDwZpZbwdMMW6qYsMYzUO9w+Gjva4CD+VtJebeBiobOTxRIju+1UkDvBw O5Ukn+knFokHUNZMjME8455R8QGAyoXU/eSlqZZSV0Z34041h32ysFfW5Fk4dqlMOxFynmkpoEJ lraA3idYyvZzpy33L94dgx0d3/0kCp5tE5ZdVnHLjMeSAt9zpFuDHW4+PC0NbZm0tJDGyRlr2Ik 9LtkdezHB7FrRQJgiQafbF5m2vQUxHsERlJ2LoZc+nMV5Ciayuv6QJKWvZrqIGkbPXReUKhgudU znbmKkvv25kIzp/mL2SwRY9FIM/z47wJ4IxYT91dM43dgp/TcoU8w8yLLHO57+FZGbgV381vLL9 NkYBo7D47K4aPY0v21JEghmab3lnZHXRF0ppArgsrVK3SERBqJl273KMSPqX1MJ2yFFvk4uIy1j BPkkaebnR+e0EPuEKVj9tgxYE7yRaGAGKSL0qLAbE92OCOx7xGY3TkqI01sOd6ktAvMxHsG36Y= X-Received: by 2002:a05:6512:12cb:b0:5b5:e265:5215 with SMTP id 2adb3069b0e04-5b8b66547c1mr1634916e87.22.1789569449626; Wed, 16 Sep 2026 07:37:29 -0700 (PDT) Received: from dau-home-pc.megasoftware.org ([95.139.134.117]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b8b57eb908sm955658e87.79.2026.09.16.07.37.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Sep 2026 07:37:29 -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 v3 4/9] ip_gre: add drop reasons to the RX path Date: Wed, 16 Sep 2026 17:37:12 +0300 Message-ID: <20260916143717.1875082-5-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260916143717.1875082-1-littlesmilingcloud@gmail.com> References: <20260916143717.1875082-1-littlesmilingcloud@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" A packet that reaches gre_rcv() and does not belong to any tunnel is dropped, after an ICMP port unreachable is sent back, with a plain kfree_skb(). This is the GRE counterpart of a UDP packet hitting no socket, and by far the most common way a GRE packet is dropped on receive, yet nothing tells it apart from a malformed one. Add SKB_DROP_REASON_GRE_TUNNEL_NOT_FOUND for it, in the spirit of the existing SKB_DROP_REASON_VXLAN_VNI_NOT_FOUND, and report it from erspan_rcv() and __ipgre_rcv() through a new output parameter, so that a failed lookup is not reported the same way as a header that could not be pulled or as a metadata allocation failure. The length checks reuse SKB_DROP_REASON_HDR_TRUNC. The __iptunnel_pull_header() failures reuse SKB_DROP_REASON_NOMEM instead: the helper returns -ENOMEM for every failure mode, and besides a short header it also fails when skb_unclone() cannot allocate, so a truncation reason would be wrong there. vxlan_rcv() labels the same helper the same way. 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 | 37 +++++++++++++++++++++++------------ 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/include/net/dropreason-core.h b/include/net/dropreason-core.h index 6ae7a604722d..fa8bd552122f 100644 --- a/include/net/dropreason-core.h +++ b/include/net/dropreason-core.h @@ -133,6 +133,7 @@ FN(TNL_OLD_SEQ) \ FN(GRE_INVALID_HDR) \ FN(GRE_CSUM) \ + FN(GRE_TUNNEL_NOT_FOUND) \ FNe(MAX) =20 /** @@ -637,6 +638,11 @@ enum skb_drop_reason { SKB_DROP_REASON_GRE_INVALID_HDR, /** @SKB_DROP_REASON_GRE_CSUM: GRE checksum error */ SKB_DROP_REASON_GRE_CSUM, + /** + * @SKB_DROP_REASON_GRE_TUNNEL_NOT_FOUND: no GRE tunnel found for the + * endpoints and the key the packet carries. + */ + SKB_DROP_REASON_GRE_TUNNEL_NOT_FOUND, /** * @SKB_DROP_REASON_MAX: the maximum of core drop reasons, which * shouldn't be used as a real 'reason' - only for tracing code gen diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 1894c5746a73..dc203937eb9f 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -265,7 +265,7 @@ static bool is_erspan_type1(int gre_hdr_len) } =20 static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi, - int gre_hdr_len) + int gre_hdr_len, enum skb_drop_reason *reason) { struct net *net =3D dev_net(skb->dev); struct metadata_dst *tun_dst =3D NULL; @@ -289,8 +289,10 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_= ptk_info *tpi, iph->saddr, iph->daddr, 0); } else { if (unlikely(!pskb_may_pull(skb, - gre_hdr_len + sizeof(*ershdr)))) + gre_hdr_len + sizeof(*ershdr)))) { + *reason =3D SKB_DROP_REASON_HDR_TRUNC; return PACKET_REJECT; + } =20 ershdr =3D (struct erspan_base_hdr *)(skb->data + gre_hdr_len); ver =3D ershdr->ver; @@ -306,8 +308,10 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_= ptk_info *tpi, else len =3D gre_hdr_len + erspan_hdr_len(ver); =20 - if (unlikely(!pskb_may_pull(skb, len))) + if (unlikely(!pskb_may_pull(skb, len))) { + *reason =3D SKB_DROP_REASON_HDR_TRUNC; return PACKET_REJECT; + } =20 if (__iptunnel_pull_header(skb, len, @@ -327,8 +331,10 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_= ptk_info *tpi, =20 tun_dst =3D ip_tun_rx_dst(skb, flags, tun_id, sizeof(*md)); - if (!tun_dst) + if (!tun_dst) { + *reason =3D SKB_DROP_REASON_NOMEM; return PACKET_REJECT; + } =20 /* MUST set options_len before referencing options */ info =3D &tun_dst->u.tun_info; @@ -356,15 +362,17 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl= _ptk_info *tpi, ip_tunnel_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error); return PACKET_RCVD; } + *reason =3D SKB_DROP_REASON_GRE_TUNNEL_NOT_FOUND; return PACKET_REJECT; =20 drop: - kfree_skb(skb); + kfree_skb_reason(skb, SKB_DROP_REASON_NOMEM); return PACKET_RCVD; } =20 static int __ipgre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi, - struct ip_tunnel_net *itn, int hdr_len, bool raw_proto) + struct ip_tunnel_net *itn, int hdr_len, bool raw_proto, + enum skb_drop_reason *reason) { struct metadata_dst *tun_dst =3D NULL; const struct iphdr *iph; @@ -400,22 +408,25 @@ static int __ipgre_rcv(struct sk_buff *skb, const str= uct tnl_ptk_info *tpi, =20 tun_id =3D key32_to_tunnel_id(tpi->key); tun_dst =3D ip_tun_rx_dst(skb, flags, tun_id, 0); - if (!tun_dst) + if (!tun_dst) { + *reason =3D SKB_DROP_REASON_NOMEM; return PACKET_REJECT; + } } =20 ip_tunnel_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error); return PACKET_RCVD; } + *reason =3D SKB_DROP_REASON_GRE_TUNNEL_NOT_FOUND; return PACKET_NEXT; =20 drop: - kfree_skb(skb); + kfree_skb_reason(skb, SKB_DROP_REASON_NOMEM); return PACKET_RCVD; } =20 static int ipgre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi, - int hdr_len) + int hdr_len, enum skb_drop_reason *reason) { struct net *net =3D dev_net(skb->dev); struct ip_tunnel_net *itn; @@ -426,13 +437,13 @@ static int ipgre_rcv(struct sk_buff *skb, const struc= t tnl_ptk_info *tpi, else itn =3D net_generic(net, ipgre_net_id); =20 - res =3D __ipgre_rcv(skb, tpi, itn, hdr_len, false); + res =3D __ipgre_rcv(skb, tpi, itn, hdr_len, false, reason); if (res =3D=3D PACKET_NEXT && tpi->proto =3D=3D htons(ETH_P_TEB)) { /* ipgre tunnels in collect metadata mode should receive * also ETH_P_TEB traffic. */ itn =3D net_generic(net, ipgre_net_id); - res =3D __ipgre_rcv(skb, tpi, itn, hdr_len, true); + res =3D __ipgre_rcv(skb, tpi, itn, hdr_len, true, reason); } return res; } @@ -457,12 +468,12 @@ static int gre_rcv(struct sk_buff *skb) =20 if (unlikely(tpi.proto =3D=3D htons(ETH_P_ERSPAN) || tpi.proto =3D=3D htons(ETH_P_ERSPAN2))) { - if (erspan_rcv(skb, &tpi, hdr_len) =3D=3D PACKET_RCVD) + if (erspan_rcv(skb, &tpi, hdr_len, &reason) =3D=3D PACKET_RCVD) return 0; goto out; } =20 - if (ipgre_rcv(skb, &tpi, hdr_len) =3D=3D PACKET_RCVD) + if (ipgre_rcv(skb, &tpi, hdr_len, &reason) =3D=3D PACKET_RCVD) return 0; =20 out: --=20 2.47.3 From nobody Fri Sep 25 04:38:26 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 DFDF353444B for ; Wed, 16 Sep 2026 14:37: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=1789569455; cv=none; b=hGtYeBvRYEuuArCLDm/tDM4xDW+WrXy85QB2o4JBQBRD35GPoPsnQ1oSsuD5WV2AAKz9MYP+fyIm1siSZOpcZ6rUGneKzk7yii/Ji4IhpSVxp+3IP3x++e0AVacYQu3lMsdfKMNv8sYcmtBe9a+N5IenXZ3vXntAyAm3g0P0kLg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789569455; c=relaxed/simple; bh=jS+nc6FbKntG9f5xc9im/V7LZiEbxMbgUYbRLWRapl0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ZNhfCORCOfXdcHK3SGCMMYMw0qFSrtIIKS++fC6ZCC2vOQb2ZY+wzSBxR5lNFUFEQiczjhOlRP2AwT5vcAYbfmuZWhmmRHqI/Wq8czoNhdJXp+nVje5/QW5lJUGujq+I16gNQMOatGmgyirJSAHKQtHj05xfrhiOqLHe2ux8/Ag= 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=UFKKQtAN; 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="UFKKQtAN" Received: by mail-lf2-f12.google.com with SMTP id 2adb3069b0e04-5b5e4f1e419so335119e87.0 for ; Wed, 16 Sep 2026 07:37:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789569451; x=1790174251; 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=4FblbYierjHzQHjiMdh07O9Nt/6J/OwumlrTj+pnoQo=; b=UFKKQtANTJkA9qHptmFGSWm8ZdgznUCG4vf6DBOhjfWArS8vYEDkle1lbRaLAL4Zm5 dNEx4FZ2hZ0YySKA0+QZjlMMuS/x1mUOSUW35s/bzUkzCMQG4+/e1kvrmL6l8vPqenTi sPZcTF8ueeFt4YE6orOuDaFAvxEvnkg2/xxtInlF5SCb7SMVoGk4y9LhpLEX304byuuR 42mHPfE3UDSO7pqPeNaUOmVqh+kTxbL/01A4KvuOL+PtiNQRRXJcDfl60KQhhjNz3+1z I8p4+dq7ZZ2gioRxeaA30z+lQCDzz7/awGkL6fefpEOK8g54IppWTn/PZWBo99jQaFED za2g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789569451; x=1790174251; 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=4FblbYierjHzQHjiMdh07O9Nt/6J/OwumlrTj+pnoQo=; b=1GhYdTe2QHLqxZcR0YbIMD7ApxAMaT382O1bI1AeX52GQS8qGvRVMCg8zpxkKB2sbw ZZQ81MPgIChjanoenkXnRVJzr7xgr77rH6mkbznL1CDFZfdYhrYsQ1UGEY53yjEjtVWU nNkM3s0Cmuoe0AD77NgnWDZk3T/TANK/BDcWeE4ZuZC37GZxk/rhuXoilAUleH4B4NcE EwFY+y17QK6WsRYBqPWf2gq7WuZn/SyVVVkSBWsk2WnjbytUwFCSY25vTw0HRucQIpYo gq77yTiFagJrjilPqwj2uWgu0693QdSsYgPirZbvtY1j5KfXC2DRF6gS3GX/f18jZwy9 L3Iw== X-Forwarded-Encrypted: i=1; AKwUvBwRTXjqjbMOZdwt7YZhIHMT39jWbGCDJ5hBsCWHYinCVFL4Q/7H6v2Z+WrEwJiGtHLRwhpdNTy8nIwNX7c=@vger.kernel.org X-Gm-Message-State: AFuF++mVz0prPqaiGSMM1zKzWqDqbkF+eGYynPcvgV3M0RA+T/u5MjT0 vitniccXX6nEyTv7i/znwzoBfmKsbDVX0QWdYGiYb2qyK/UOKgL2yTuT X-Gm-Gg: AYBFou0asRacjUao95G24NihWMZHKEHV809gBbFeUFBHhYNMiCJ32qCIKI+QAJYaPyg gyPpbcDn6rTM11LxZFep081nuR5r7yCdhS+vCtviBsXwbRMz42HTRWjl5wun+RDdc15TpKzqoQF yKF01DfsDYnGcGNGa0V2ns8ASC7vuAS3+iCKDkFAmE5e98VQT0ilfz/oFW5e+udA/tC5ZRFXEsi /vL5IGksJJb7fOe7eyUrrHsiqwm29N0hY1ec65C+O3yOm/B3NTVhoE4Lc6/u406DoKm+Z1IYFvd PzWiCzrO+zNqSN6Sr6n2pC4w8U23mTDGNR2LOYW6cqxzGnDDoDDoS2A+gAclBc5VCiGhBgtaoYu Io/KQorqg/q9CiyPGkSPYfV+ZytB5z9iQjX8AIfJ1L4S9Pe90nVFv/lRMNdfhSXNGAD7crL7khT SRp6/6gRKugZXFuAaTOIPRQrFONBPSnt5/bJ3Ly8i9FLnETDigyEUdtaFRmjFTm227VUeaNcU3b IORRAlZNHHo7uxzt3EXuHK58JZOdMHI3N4lcb3WYgGPS+nRxClaypbIh3Bus9yB9S/NwITXgeY= X-Received: by 2002:a05:6512:230f:b0:5b6:10bc:b864 with SMTP id 2adb3069b0e04-5b8b63f8893mr693262e87.18.1789569450683; Wed, 16 Sep 2026 07:37:30 -0700 (PDT) Received: from dau-home-pc.megasoftware.org ([95.139.134.117]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b8b57eb908sm955658e87.79.2026.09.16.07.37.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Sep 2026 07:37: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 v3 5/9] ip6_gre: add drop reasons to the RX path Date: Wed, 16 Sep 2026 17:37:13 +0300 Message-ID: <20260916143717.1875082-6-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260916143717.1875082-1-littlesmilingcloud@gmail.com> References: <20260916143717.1875082-1-littlesmilingcloud@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Mirror the previous patch on the IPv6 side: report SKB_DROP_REASON_GRE_TUNNEL_NOT_FOUND when no tunnel matches the packet, and tell that apart from a header that is too short (SKB_DROP_REASON_HDR_TRUNC) and from the allocation failures behind __iptunnel_pull_header() and the metadata dst (SKB_DROP_REASON_NOMEM), which so far all ended up in the same plain kfree_skb() in gre_rcv(). ip6gre_rcv() and ip6erspan_rcv() get the same output parameter as their IPv4 counterparts. Assisted-by: Claude-Code:claude-opus-5 Signed-off-by: Anton Danilov --- net/ipv6/ip6_gre.c | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 78854cc2dac9..0b270f4ac774 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -454,7 +454,8 @@ static int ip6gre_err(struct sk_buff *skb, struct inet6= _skb_parm *opt, return 0; } =20 -static int ip6gre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi) +static int ip6gre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi, + enum skb_drop_reason *reason) { const struct ipv6hdr *ipv6h; struct ip6_tnl *tunnel; @@ -473,8 +474,10 @@ static int ip6gre_rcv(struct sk_buff *skb, const struc= t tnl_ptk_info *tpi) tun_id =3D key32_to_tunnel_id(tpi->key); =20 tun_dst =3D ipv6_tun_rx_dst(skb, flags, tun_id, 0); - if (!tun_dst) + if (!tun_dst) { + *reason =3D SKB_DROP_REASON_NOMEM; return PACKET_REJECT; + } =20 ip6_tnl_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error); } else { @@ -484,12 +487,14 @@ static int ip6gre_rcv(struct sk_buff *skb, const stru= ct tnl_ptk_info *tpi) return PACKET_RCVD; } =20 + *reason =3D SKB_DROP_REASON_GRE_TUNNEL_NOT_FOUND; return PACKET_REJECT; } =20 static int ip6erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi, - int gre_hdr_len) + int gre_hdr_len, + enum skb_drop_reason *reason) { struct erspan_base_hdr *ershdr; const struct ipv6hdr *ipv6h; @@ -497,8 +502,10 @@ static int ip6erspan_rcv(struct sk_buff *skb, struct ip6_tnl *tunnel; u8 ver; =20 - if (unlikely(!pskb_may_pull(skb, sizeof(*ershdr)))) + if (unlikely(!pskb_may_pull(skb, sizeof(*ershdr)))) { + *reason =3D SKB_DROP_REASON_HDR_TRUNC; return PACKET_REJECT; + } =20 ipv6h =3D ipv6_hdr(skb); ershdr =3D (struct erspan_base_hdr *)skb->data; @@ -510,13 +517,17 @@ static int ip6erspan_rcv(struct sk_buff *skb, if (tunnel) { int len =3D erspan_hdr_len(ver); =20 - if (unlikely(!pskb_may_pull(skb, len))) + if (unlikely(!pskb_may_pull(skb, len))) { + *reason =3D SKB_DROP_REASON_HDR_TRUNC; return PACKET_REJECT; + } =20 if (__iptunnel_pull_header(skb, len, htons(ETH_P_TEB), - false, false) < 0) + false, false) < 0) { + *reason =3D SKB_DROP_REASON_NOMEM; return PACKET_REJECT; + } =20 if (tunnel->parms.collect_md) { struct erspan_metadata *pkt_md, *md; @@ -532,8 +543,10 @@ static int ip6erspan_rcv(struct sk_buff *skb, =20 tun_dst =3D ipv6_tun_rx_dst(skb, flags, tun_id, sizeof(*md)); - if (!tun_dst) + if (!tun_dst) { + *reason =3D SKB_DROP_REASON_NOMEM; return PACKET_REJECT; + } =20 /* MUST set options_len before referencing options */ info =3D &tun_dst->u.tun_info; @@ -564,6 +577,7 @@ static int ip6erspan_rcv(struct sk_buff *skb, return PACKET_RCVD; } =20 + *reason =3D SKB_DROP_REASON_GRE_TUNNEL_NOT_FOUND; return PACKET_REJECT; } =20 @@ -577,17 +591,19 @@ static int gre_rcv(struct sk_buff *skb) if (hdr_len < 0) goto drop; =20 - if (iptunnel_pull_header(skb, hdr_len, tpi.proto, false)) + if (iptunnel_pull_header(skb, hdr_len, tpi.proto, false)) { + reason =3D SKB_DROP_REASON_NOMEM; goto drop; + } =20 if (unlikely(tpi.proto =3D=3D htons(ETH_P_ERSPAN) || tpi.proto =3D=3D htons(ETH_P_ERSPAN2))) { - if (ip6erspan_rcv(skb, &tpi, hdr_len) =3D=3D PACKET_RCVD) + if (ip6erspan_rcv(skb, &tpi, hdr_len, &reason) =3D=3D PACKET_RCVD) return 0; goto out; } =20 - if (ip6gre_rcv(skb, &tpi) =3D=3D PACKET_RCVD) + if (ip6gre_rcv(skb, &tpi, &reason) =3D=3D PACKET_RCVD) return 0; =20 out: --=20 2.47.3 From nobody Fri Sep 25 04:38:26 2026 Received: from mail-lr2-f22.google.com (mail-lr2-f22.google.com [74.125.230.86]) (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 A08D053D0C9 for ; Wed, 16 Sep 2026 14:37:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.230.86 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789569457; cv=none; b=YglZMT343OiUv7lZtSH8uK0nAZ99tgs6vVAklTHrlJedSsoDZcsdqrOS4KPFc8KYNY5r/Zy4jAlBBv5i0mej9rYY/Umr0I3UrstHfL/ShMI3BVVR5/RAv4mpXdjbFdTfCCGhEcLPer05bX14W0ThJZ+phyei3m9xwO4zVsY1vbQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789569457; c=relaxed/simple; bh=lxp4NJkYO7E48ja5AHkMY7+Cyu/qdRcqrWCWF1iYoYQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CT2WPY9teYVxQxdgPSFMqrfaOrBThM9YAMTuRfl4SHbUgIaqt/r2jOyFbjhc3L7FXEuoJIHY7zSoPinOYu6NplRj1loDHPrY7YR/Og1l6CydrHF9po48HFPwU4kdj4xN8ULE8UyNmi6J5ef7/7ZCdyiK98Ts45Ci3CzvKCyYso0= 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=M6N83kz+; arc=none smtp.client-ip=74.125.230.86 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="M6N83kz+" Received: by mail-lr2-f22.google.com with SMTP id 38308e7fff4ca-3a2ff04155bso8919951fa.1 for ; Wed, 16 Sep 2026 07:37:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789569452; x=1790174252; 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=7+2xUfpNk80vOApeT5HP7l0i/3VJUg0mGr1lclpVbwY=; b=M6N83kz+t1eJoUlU6Ks33mso4Gz2zS3UHXekz2EjI7hsHL5Gc1PnutXWXo6WSEsJtM 7fIP5lNqZ8L3QIoD2Ivt94hudAc0HlUTNrSp7ZWe1V05Tsm0UoY6c6sAQXiG4bvyygcG 1cumdXY1s2KdrSe3c5Qvea+gI7dq7s7LA0OZRl1FczXlQxCelwJQsvFVevv29DYRGdZ8 hqCNDOumKjPP8BGcvzdKGDeNXOhoqnaBfDiPyjuDbMV6lDTnsUGtrzaCkov1C0211Ycr sbfzgfx/F4uD/bGOjQM+Eaq/prQX0Ize2IP5te2T5mXzy0U0cEaqmqN1z/7B5CUJOIDF eBsA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789569452; x=1790174252; 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=7+2xUfpNk80vOApeT5HP7l0i/3VJUg0mGr1lclpVbwY=; b=rwbFYMdo4lnZDUMbgi3M5RelbKnI49vlL4ZpB4X+DkhGCgByz5vr5a2dJ/VvLggAU7 t+eQIULLDGfKytp1wQuI+Zi7Lqh8z1nUPxlNlrcs5NrsDSbmoLZbue4Vc89hTLyqSzvq oFGmyxtKi8ZEsiaWc+w3+6rgrZ+v6pJDHB/j6tR52dph0yMWQX5RCj+lzLhUrlXlSwMe 2UkQwZCtodF6EYU/C/NscunrKYr7vXGar5wEsigcO1LoVZst6wELs/SLtUpC2dTmvTJT wbszr1Sa0GtW4dkTuUhBbhqqtKIPVGFggHnMbS2RhT4u4CAq6nE88B92BnWfzs4LlwHG Oq7g== X-Forwarded-Encrypted: i=1; AKwUvBx4keIub5zV4zM6PAw1V+uio+shZf8LvaFlxynZKu4wsN1Jj+UXiDA/WFQkWc8ITxR2tmD7uH8A7Kmamr4=@vger.kernel.org X-Gm-Message-State: AFuF++naJvnCfIy/JoxnYKMR2MNOrLGOltSVbjVnZMgTCJjDB9Xm6snz 66AUkLZ9vsehI4IL6BLT5x3mS9LMEJUIF5XU1O5y+mpXVgUbkoEmpGI2 X-Gm-Gg: AYBFou3DBjM0nxzkQ1pPnhgxFeI9msBIv3rAgAithbkLCoEaOjUUA0nGT9XeNPK8KUC NT2P8+Li/omSLbIBT06Wdwc9aextNzcTB5Bs4CZYaQtoscTj1F009D++AWr1XFLiYRZiGwGctHG hjHu7KrCT4rGgjViZMvm4xN9W/fRDrtiENLv7a8WIj4/yBKH5NBAO9UZr8IR0Iw90IrTBbQCNwZ qv6yua4S0JC3NfjrjqLuklH8HCQ+t9ud4ArUgJfwR1Gm3Sfftpnmnw1cJpkN/nOQpkF4spoftLt EIrFPHXjKXPEmvlkqyR/lkKEE3zZHBwsgUa85jJilI7mP1ENXr8OpHKS8F1CdY4qVuQPI2ZZfEN ySN2dWsNWwbdcgUf/93L0h6u/dbnLwPBmMBo4z6LBiq89lfP2Gc88qz1tGeffu3ew4E0fPlopWh 9QeC4pxuKd1u5+ZunC69WKNSYLv4UKf1Qt23jYl0x1fNE3TMmIHcfWYHHDUb9ETpadwnnzO3BRU PiEBSRP+A1GMfcSgNxhNNuhywp2qUOEQFmg7IJrRbatAsZc0fgt9sVXA69trbDtgg== X-Received: by 2002:a05:6512:3a93:b0:5b6:1a7c:aa1f with SMTP id 2adb3069b0e04-5b8b6655de0mr834514e87.55.1789569451985; Wed, 16 Sep 2026 07:37:31 -0700 (PDT) Received: from dau-home-pc.megasoftware.org ([95.139.134.117]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b8b57eb908sm955658e87.79.2026.09.16.07.37.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Sep 2026 07:37:31 -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 v3 6/9] ip_tunnel: add drop reasons to the transmit path Date: Wed, 16 Sep 2026 17:37:14 +0300 Message-ID: <20260916143717.1875082-7-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260916143717.1875082-1-littlesmilingcloud@gmail.com> References: <20260916143717.1875082-1-littlesmilingcloud@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" ip_tunnel_xmit() and ip_md_tunnel_xmit() encapsulate packets that the tunnel forwards, and every failure on that path ends in the same plain kfree_skb(). The device counters separate them a little, but they are too coarse to act on: tx_errors alone covers an encapsulation failure, a routing failure, a lookup loop and a packet that is simply too big. The last one deserves attention. tnl_update_pmtu() returns -E2BIG for a packet larger than the path MTU, an IPv4 one with the DF bit set or any IPv6 one, after it has already sent the ICMP error back to the sender. That is path MTU discovery working as intended, yet it lands in tx_errors next to genuine failures, so a MTU black hole cannot be told from a broken route by looking at the counters. No new reason is needed for most of it: - SKB_DROP_REASON_PKT_TOO_BIG for the case above, - SKB_DROP_REASON_IP_OUTNOROUTES when no route is found, - SKB_DROP_REASON_RECURSION_LIMIT when the route points back at the tunnel device itself, which is the "dead loop on virtual device" that reason describes, - SKB_DROP_REASON_NOMEM when the headroom cannot be expanded, - SKB_DROP_REASON_NEIGH_CREATEFAIL when the NBMA neighbour lookup fails, SKB_DROP_REASON_NO_TX_TARGET when no destination can be derived at all, and SKB_DROP_REASON_UNHANDLED_PROTO for a payload that is neither IPv4 nor IPv6, - SKB_DROP_REASON_TUNNEL_TXINFO, which already documents a packet reaching an external mode device without metadata, for the collect_md path. Only the encapsulation failure has no fitting reason, so add SKB_DROP_REASON_TNL_ENCAP for it. Drop reasons on transmit are not new: vxlan already reports several of them from its xmit path, and ip_tunnel_core.c reports SKB_DROP_REASON_RECURSION_LIMIT. Assisted-by: Claude-Code:claude-opus-5 Signed-off-by: Anton Danilov --- include/net/dropreason-core.h | 7 ++++++ net/ipv4/ip_tunnel.c | 41 ++++++++++++++++++++++++++++------- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/include/net/dropreason-core.h b/include/net/dropreason-core.h index fa8bd552122f..30378a0d2272 100644 --- a/include/net/dropreason-core.h +++ b/include/net/dropreason-core.h @@ -134,6 +134,7 @@ FN(GRE_INVALID_HDR) \ FN(GRE_CSUM) \ FN(GRE_TUNNEL_NOT_FOUND) \ + FN(TNL_ENCAP) \ FNe(MAX) =20 /** @@ -643,6 +644,12 @@ enum skb_drop_reason { * endpoints and the key the packet carries. */ SKB_DROP_REASON_GRE_TUNNEL_NOT_FOUND, + /** + * @SKB_DROP_REASON_TNL_ENCAP: failed to build the + * encapsulation header of a tunnel, e.g. an unknown or + * unregistered encapsulation type. + */ + SKB_DROP_REASON_TNL_ENCAP, /** * @SKB_DROP_REASON_MAX: the maximum of core drop reasons, which * shouldn't be used as a real 'reason' - only for tracing code gen diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index 0260a97e990e..e7757c0a09be 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -580,6 +580,7 @@ static int tnl_update_pmtu(struct net_device *dev, stru= ct sk_buff *skb, void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, u8 proto, int tunnel_hlen) { + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; struct ip_tunnel *tunnel =3D netdev_priv(dev); u32 headroom =3D sizeof(struct iphdr); struct ip_tunnel_info *tun_info; @@ -593,8 +594,10 @@ void ip_md_tunnel_xmit(struct sk_buff *skb, struct net= _device *dev, =20 tun_info =3D skb_tunnel_info(skb); if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX) || - ip_tunnel_info_af(tun_info) !=3D AF_INET)) + ip_tunnel_info_af(tun_info) !=3D AF_INET)) { + reason =3D SKB_DROP_REASON_TUNNEL_TXINFO; goto tx_error; + } key =3D &tun_info->key; memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); inner_iph =3D (const struct iphdr *)skb_inner_network_header(skb); @@ -613,8 +616,10 @@ void ip_md_tunnel_xmit(struct sk_buff *skb, struct net= _device *dev, if (!tunnel_hlen) tunnel_hlen =3D ip_encap_hlen(&tun_info->encap); =20 - if (ip_tunnel_encap(skb, &tun_info->encap, &proto, &fl4) < 0) + if (ip_tunnel_encap(skb, &tun_info->encap, &proto, &fl4) < 0) { + reason =3D SKB_DROP_REASON_TNL_ENCAP; goto tx_error; + } =20 use_cache =3D ip_tunnel_dst_cache_usable(skb, tun_info); if (use_cache) @@ -623,6 +628,7 @@ void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_= device *dev, rt =3D ip_route_output_key(tunnel->net, &fl4); if (IS_ERR(rt)) { DEV_STATS_INC(dev, tx_carrier_errors); + reason =3D SKB_DROP_REASON_IP_OUTNOROUTES; goto tx_error; } if (use_cache) @@ -632,6 +638,7 @@ void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_= device *dev, if (rt->dst.dev =3D=3D dev) { ip_rt_put(rt); DEV_STATS_INC(dev, collisions); + reason =3D SKB_DROP_REASON_RECURSION_LIMIT; goto tx_error; } =20 @@ -640,6 +647,7 @@ void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_= device *dev, if (tnl_update_pmtu(dev, skb, rt, df, inner_iph, tunnel_hlen, key->u.ipv4.dst, true)) { ip_rt_put(rt); + reason =3D SKB_DROP_REASON_PKT_TOO_BIG; goto tx_error; } =20 @@ -657,6 +665,7 @@ void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_= device *dev, headroom +=3D LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len; if (skb_cow_head(skb, headroom)) { ip_rt_put(rt); + reason =3D SKB_DROP_REASON_NOMEM; goto tx_dropped; } =20 @@ -671,13 +680,14 @@ void ip_md_tunnel_xmit(struct sk_buff *skb, struct ne= t_device *dev, tx_dropped: DEV_STATS_INC(dev, tx_dropped); kfree: - kfree_skb(skb); + kfree_skb_reason(skb, reason); } EXPORT_SYMBOL_GPL(ip_md_tunnel_xmit); =20 void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, const struct iphdr *tnl_params, u8 protocol) { + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; struct ip_tunnel *tunnel =3D netdev_priv(dev); struct ip_tunnel_info *tun_info =3D NULL; const struct iphdr *inner_iph; @@ -705,9 +715,15 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_de= vice *dev, =20 if (!skb_dst(skb)) { DEV_STATS_INC(dev, tx_fifo_errors); + reason =3D SKB_DROP_REASON_NO_TX_TARGET; goto tx_error; } =20 + /* Only the branches below can derive a destination. If + * none of them matches, the payload protocol is not one + * this tunnel can carry. + */ + reason =3D SKB_DROP_REASON_UNHANDLED_PROTO; tun_info =3D skb_tunnel_info(skb); if (tun_info && (tun_info->mode & IP_TUNNEL_INFO_TX) && ip_tunnel_info_af(tun_info) =3D=3D AF_INET && @@ -728,8 +744,10 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_de= vice *dev, =20 neigh =3D dst_neigh_lookup(skb_dst(skb), &ipv6_hdr(skb)->daddr); - if (!neigh) + if (!neigh) { + reason =3D SKB_DROP_REASON_NEIGH_CREATEFAIL; goto tx_error; + } =20 addr6 =3D (const struct in6_addr *)&neigh->primary_key; addr_type =3D ipv6_addr_type(addr6); @@ -746,8 +764,10 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_de= vice *dev, dst =3D addr6->s6_addr32[3]; } neigh_release(neigh); - if (do_tx_error_icmp) + if (do_tx_error_icmp) { + reason =3D SKB_DROP_REASON_NO_TX_TARGET; goto tx_error_icmp; + } } #endif else @@ -774,8 +794,10 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_de= vice *dev, tunnel->net, READ_ONCE(tunnel->parms.link), tunnel->fwmark, skb_get_hash(skb), 0); =20 - if (ip_tunnel_encap(skb, &tunnel->encap, &protocol, &fl4) < 0) + if (ip_tunnel_encap(skb, &tunnel->encap, &protocol, &fl4) < 0) { + reason =3D SKB_DROP_REASON_TNL_ENCAP; goto tx_error; + } =20 if (connected && md) { use_cache =3D ip_tunnel_dst_cache_usable(skb, tun_info); @@ -792,6 +814,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_dev= ice *dev, =20 if (IS_ERR(rt)) { DEV_STATS_INC(dev, tx_carrier_errors); + reason =3D SKB_DROP_REASON_IP_OUTNOROUTES; goto tx_error; } if (use_cache) @@ -805,6 +828,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_dev= ice *dev, if (rt->dst.dev =3D=3D dev) { ip_rt_put(rt); DEV_STATS_INC(dev, collisions); + reason =3D SKB_DROP_REASON_RECURSION_LIMIT; goto tx_error; } =20 @@ -814,6 +838,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_dev= ice *dev, =20 if (tnl_update_pmtu(dev, skb, rt, df, inner_iph, 0, 0, false)) { ip_rt_put(rt); + reason =3D SKB_DROP_REASON_PKT_TOO_BIG; goto tx_error; } =20 @@ -848,7 +873,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_dev= ice *dev, if (skb_cow_head(skb, max_headroom)) { ip_rt_put(rt); DEV_STATS_INC(dev, tx_dropped); - kfree_skb(skb); + kfree_skb_reason(skb, SKB_DROP_REASON_NOMEM); return; } =20 @@ -864,7 +889,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_dev= ice *dev, #endif tx_error: DEV_STATS_INC(dev, tx_errors); - kfree_skb(skb); + kfree_skb_reason(skb, reason); } EXPORT_SYMBOL_GPL(ip_tunnel_xmit); =20 --=20 2.47.3 From nobody Fri Sep 25 04:38:26 2026 Received: from mail-lr2-f14.google.com (mail-lr2-f14.google.com [74.125.230.78]) (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 711E553FD24 for ; Wed, 16 Sep 2026 14:37:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.230.78 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789569459; cv=none; b=ZLbDHa5MyGnF5gw8oK2Poj/giYPozpS+A+2npHr1OiR9LW7UFLEAasa44zf/EoWjsEMvdgAwSoUZy+5Fir3rCOIBKB8s3jwMaf3MMxjcvCxVa4sLbuvCqVFjYcqfy4AilaMoBuAOE265obuObhAnZ3VQEoF4FOwraGLUnjtiiiQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789569459; c=relaxed/simple; bh=dojxVXG3sNV8ng6Av750Gp8Fk5X4IYoTxCHMc36gIOA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KEaHMXHYrte7rOhGXbT1BgxI4aYvzGLMJzXupTiR6kV7Je7lp8DIAabUUBqs0JPJnTrXMjhE3RiOu8n0zXaZn8/AODbiGZBV8+RwUcDl1DhaGZdCmgc+KC0lrm7OrwbSNm0nNW7oBpXPHntDzD73KaWXexJZNZkKNKWanbPFua4= 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=hmPJ8Az5; arc=none smtp.client-ip=74.125.230.78 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="hmPJ8Az5" Received: by mail-lr2-f14.google.com with SMTP id 38308e7fff4ca-3a5b2864f1cso8196671fa.3 for ; Wed, 16 Sep 2026 07:37:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789569453; x=1790174253; 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=hESk+k+74OP8gnuSHzDBoTsGcSND2qSgXj7zXhmxe10=; b=hmPJ8Az5N8Ig3c3IWC9v6SQ9aq/m8z+K+rqv8RS3XuQd7gITkUBZ/h0Tx2DYpGMEk/ 57CNkMDZih/nMhV4chkocXXam2CQmBF8HPawL3JkQ9fFIAKT9aUfI3CLPO4zGRiDegrw zP3zbBDYvTX53MCKZwZB0jDcM3oZ76qmWxjLK39ZfXw8E1DmscMfHD7Dmq3keuTwO04T y5FWgrn9qUy7irvsJsRw/gYYxh7wWOAwphlLmExJD4KGoc3/cCpTvQio37kwk4/QUawa Ss2cRxMHCJ8fGNlg1BZIwXdiTaOUXl4MkMqN1olR5nduIbBUUQCCtz8b3utFY4vmMpxv iF1Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789569453; x=1790174253; 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=hESk+k+74OP8gnuSHzDBoTsGcSND2qSgXj7zXhmxe10=; b=V9dysGsmrzsebQTJ/4Ymw+KTE5VcqZKERbQ61Bsix5q9yNxDW2PKa61KoTQTJ795rC +Hj+4+HAIj03IUs3W3x0WmDFwGKpV8CqhBsldyZNaKzMKXGopyGe9BmvejIR3k5lO0tS 9fUYlIf09guAYqwOufmDm9+JWd6EB7qHhIDOzfK21uJoHO9biCDzVvjCygz4g2Flyb8w ewZY40Mt9CRqs6CuBq95eBhjoVUZf/TI8jWf0dhrS9r3gFAaniaSX9u2cKQvUAnSC82V WeuVlRyz4jYHPGaGc1B9fLfkQJR6aCZjLXQjOcWh6BIGEG31tjgWilrdjhUX/6+gRWx4 YtMg== X-Forwarded-Encrypted: i=1; AKwUvBxplqIOXk/ts+krofU3acEjs2oz+ePRZIehI1w+hbdsyhEeLympX7uczDNQtqynYNeqyg2m5ewWweiEW+Y=@vger.kernel.org X-Gm-Message-State: AFuF++kYcDyNoYE45OpBELFC2TQ3SUGRUcl58mYw5xo2zgZBCKDvbPFh zhNCabliyX/QnEt+qe9OQeHA8TCHz7TXNv+oOnRTatnNBJ7VhGKi2iNP X-Gm-Gg: AYBFou3h6ilqpXeSwHb7Ch7zlVRKjCJK1Xh5qu7DxqGPfw3z4WipZiR3MGUk8IU/F/S mCJrtFKBsHDgGhL8Gy5GpVQJyFNENufaTj/vOpnMdVRgUp08tJNmR1eeGZGrMhauJ9u06olml6r 5qWlGwdnGJLYF0Vx5Y8lrLskNNKGjwIbfcpbTSlq/SXUAhsGc/oVt/qDAksnUvCphvZT9NQsnJP LCRVpuQlCTEvHhMLn0nCdncczK9dUYIlZFl/2dRw2fbeBHMuwDpRlkTmY2xHJTBlEg+qcu7Qb7q uITaze2P+AXiVCU4+7wj8UYX5KQlBw3VPlebnhfYl3hLCU4T028Qbktp7eBmXrCReix/vY8Hv+7 XyXXHqfJRbCy0EUcugzJid3WOfosrc2aWDYa+EiU2FSID0KaMlFISvIbjmRM52BtnfEpesMlH0q zAXOodiUM0SbrMm1C/wl8jlzTbd75fPNzF9ab5H6IElFhsTLsbLFdfPl0TON+3oGw8Ezjvn/umE eoCbqwA3qXmcfByTzbN3+8c7D7EuRysmQdOVocMa3YZNKax4dg90R250IcJYDF/ X-Received: by 2002:a05:6512:3f0d:b0:5b8:9943:68dd with SMTP id 2adb3069b0e04-5b8b660c30amr860185e87.7.1789569453093; Wed, 16 Sep 2026 07:37:33 -0700 (PDT) Received: from dau-home-pc.megasoftware.org ([95.139.134.117]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b8b57eb908sm955658e87.79.2026.09.16.07.37.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Sep 2026 07:37:32 -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 v3 7/9] ip_gre: add drop reasons to the transmit path Date: Wed, 16 Sep 2026 17:37:15 +0300 Message-ID: <20260916143717.1875082-8-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260916143717.1875082-1-littlesmilingcloud@gmail.com> References: <20260916143717.1875082-1-littlesmilingcloud@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The five transmit functions of ip_gre collapse about twenty distinct failures into a plain kfree_skb() and a tx_dropped increment, which says nothing beyond "the tunnel did not send it". No new reason is needed. The length helpers already compute one, so pskb_inet_may_pull_reason() and pskb_may_pull_reason() are used instead of their boolean wrappers, and the rest reuses: - SKB_DROP_REASON_NOMEM for the headroom expansions, the offload handling and the trims, - SKB_DROP_REASON_TUNNEL_TXINFO for the collect_md paths, when the metadata is missing or incomplete, - SKB_DROP_REASON_UNHANDLED_PROTO for an ERSPAN version that is not implemented, - SKB_DROP_REASON_SKB_CSUM when the checksum starts before the data the tunnel is about to send. Assisted-by: Claude-Code:claude-opus-5 Signed-off-by: Anton Danilov --- net/ipv4/ip_gre.c | 101 +++++++++++++++++++++++++++++++++------------- 1 file changed, 74 insertions(+), 27 deletions(-) diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index dc203937eb9f..373532e90dea 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -507,6 +507,7 @@ static int gre_handle_offloads(struct sk_buff *skb, boo= l csum) static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev, __be16 proto) { + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; struct ip_tunnel *tunnel =3D netdev_priv(dev); IP_TUNNEL_DECLARE_FLAGS(flags) =3D { }; struct ip_tunnel_info *tun_info; @@ -515,19 +516,25 @@ static void gre_fb_xmit(struct sk_buff *skb, struct n= et_device *dev, =20 tun_info =3D skb_tunnel_info(skb); if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX) || - ip_tunnel_info_af(tun_info) !=3D AF_INET)) + ip_tunnel_info_af(tun_info) !=3D AF_INET)) { + reason =3D SKB_DROP_REASON_TUNNEL_TXINFO; goto err_free_skb; + } =20 key =3D &tun_info->key; tunnel_hlen =3D gre_calc_hlen(key->tun_flags); =20 - if (skb_cow_head(skb, dev->needed_headroom)) + if (skb_cow_head(skb, dev->needed_headroom)) { + reason =3D SKB_DROP_REASON_NOMEM; goto err_free_skb; + } =20 /* Push Tunnel header. */ if (gre_handle_offloads(skb, test_bit(IP_TUNNEL_CSUM_BIT, - tunnel->parms.o_flags))) + tunnel->parms.o_flags))) { + reason =3D SKB_DROP_REASON_NOMEM; goto err_free_skb; + } =20 __set_bit(IP_TUNNEL_CSUM_BIT, flags); __set_bit(IP_TUNNEL_KEY_BIT, flags); @@ -544,12 +551,13 @@ static void gre_fb_xmit(struct sk_buff *skb, struct n= et_device *dev, return; =20 err_free_skb: - kfree_skb(skb); + kfree_skb_reason(skb, reason); DEV_STATS_INC(dev, tx_dropped); } =20 static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev) { + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; struct ip_tunnel *tunnel =3D netdev_priv(dev); IP_TUNNEL_DECLARE_FLAGS(flags) =3D { }; struct ip_tunnel_info *tun_info; @@ -563,29 +571,41 @@ static void erspan_fb_xmit(struct sk_buff *skb, struc= t net_device *dev) =20 tun_info =3D skb_tunnel_info(skb); if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX) || - ip_tunnel_info_af(tun_info) !=3D AF_INET)) + ip_tunnel_info_af(tun_info) !=3D AF_INET)) { + reason =3D SKB_DROP_REASON_TUNNEL_TXINFO; goto err_free_skb; + } =20 key =3D &tun_info->key; - if (!test_bit(IP_TUNNEL_ERSPAN_OPT_BIT, tun_info->key.tun_flags)) + if (!test_bit(IP_TUNNEL_ERSPAN_OPT_BIT, tun_info->key.tun_flags)) { + reason =3D SKB_DROP_REASON_TUNNEL_TXINFO; goto err_free_skb; - if (tun_info->options_len < sizeof(*md)) + } + if (tun_info->options_len < sizeof(*md)) { + reason =3D SKB_DROP_REASON_TUNNEL_TXINFO; goto err_free_skb; + } md =3D ip_tunnel_info_opts(tun_info); =20 /* ERSPAN has fixed 8 byte GRE header */ version =3D md->version; tunnel_hlen =3D 8 + erspan_hdr_len(version); =20 - if (skb_cow_head(skb, dev->needed_headroom)) + if (skb_cow_head(skb, dev->needed_headroom)) { + reason =3D SKB_DROP_REASON_NOMEM; goto err_free_skb; + } =20 - if (gre_handle_offloads(skb, false)) + if (gre_handle_offloads(skb, false)) { + reason =3D SKB_DROP_REASON_NOMEM; goto err_free_skb; + } =20 if (skb->len > dev->mtu + dev->hard_header_len) { - if (pskb_trim(skb, dev->mtu + dev->hard_header_len)) + if (pskb_trim(skb, dev->mtu + dev->hard_header_len)) { + reason =3D SKB_DROP_REASON_NOMEM; goto err_free_skb; + } truncate =3D true; } =20 @@ -617,6 +637,7 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct = net_device *dev) truncate, true); proto =3D htons(ETH_P_ERSPAN2); } else { + reason =3D SKB_DROP_REASON_UNHANDLED_PROTO; goto err_free_skb; } =20 @@ -629,7 +650,7 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct = net_device *dev) return; =20 err_free_skb: - kfree_skb(skb); + kfree_skb_reason(skb, reason); DEV_STATS_INC(dev, tx_dropped); } =20 @@ -660,11 +681,13 @@ static int gre_fill_metadata_dst(struct net_device *d= ev, struct sk_buff *skb) static netdev_tx_t ipgre_xmit(struct sk_buff *skb, struct net_device *dev) { + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; struct ip_tunnel *tunnel =3D netdev_priv(dev); IP_TUNNEL_DECLARE_FLAGS(flags); const struct iphdr *tnl_params; =20 - if (!pskb_inet_may_pull(skb)) + reason =3D pskb_inet_may_pull_reason(skb); + if (reason) goto free_skb; =20 if (tunnel->collect_md) { @@ -675,10 +698,13 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb, if (dev->header_ops) { int pull_len =3D tunnel->hlen + sizeof(struct iphdr); =20 - if (skb_cow_head(skb, 0)) + if (skb_cow_head(skb, 0)) { + reason =3D SKB_DROP_REASON_NOMEM; goto free_skb; + } =20 - if (!pskb_may_pull(skb, pull_len)) + reason =3D pskb_may_pull_reason(skb, pull_len); + if (reason) goto free_skb; =20 tnl_params =3D (const struct iphdr *)skb->data; @@ -688,25 +714,31 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb, skb_reset_mac_header(skb); =20 if (skb->ip_summed =3D=3D CHECKSUM_PARTIAL && - skb_checksum_start(skb) < skb->data) + skb_checksum_start(skb) < skb->data) { + reason =3D SKB_DROP_REASON_SKB_CSUM; goto free_skb; + } } else { - if (skb_cow_head(skb, dev->needed_headroom)) + if (skb_cow_head(skb, dev->needed_headroom)) { + reason =3D SKB_DROP_REASON_NOMEM; goto free_skb; + } =20 tnl_params =3D &tunnel->parms.iph; } =20 ip_tunnel_flags_copy(flags, tunnel->parms.o_flags); =20 - if (gre_handle_offloads(skb, test_bit(IP_TUNNEL_CSUM_BIT, flags))) + if (gre_handle_offloads(skb, test_bit(IP_TUNNEL_CSUM_BIT, flags))) { + reason =3D SKB_DROP_REASON_NOMEM; goto free_skb; + } =20 __gre_xmit(skb, dev, tnl_params, skb->protocol, flags); return NETDEV_TX_OK; =20 free_skb: - kfree_skb(skb); + kfree_skb_reason(skb, reason); DEV_STATS_INC(dev, tx_dropped); return NETDEV_TX_OK; } @@ -714,12 +746,14 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb, static netdev_tx_t erspan_xmit(struct sk_buff *skb, struct net_device *dev) { + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; struct ip_tunnel *tunnel =3D netdev_priv(dev); IP_TUNNEL_DECLARE_FLAGS(flags); bool truncate =3D false; __be16 proto; =20 - if (!pskb_inet_may_pull(skb)) + reason =3D pskb_inet_may_pull_reason(skb); + if (reason) goto free_skb; =20 if (tunnel->collect_md) { @@ -727,15 +761,21 @@ static netdev_tx_t erspan_xmit(struct sk_buff *skb, return NETDEV_TX_OK; } =20 - if (gre_handle_offloads(skb, false)) + if (gre_handle_offloads(skb, false)) { + reason =3D SKB_DROP_REASON_NOMEM; goto free_skb; + } =20 - if (skb_cow_head(skb, dev->needed_headroom)) + if (skb_cow_head(skb, dev->needed_headroom)) { + reason =3D SKB_DROP_REASON_NOMEM; goto free_skb; + } =20 if (skb->len > dev->mtu + dev->hard_header_len) { - if (pskb_trim(skb, dev->mtu + dev->hard_header_len)) + if (pskb_trim(skb, dev->mtu + dev->hard_header_len)) { + reason =3D SKB_DROP_REASON_NOMEM; goto free_skb; + } truncate =3D true; } =20 @@ -756,6 +796,7 @@ static netdev_tx_t erspan_xmit(struct sk_buff *skb, truncate, true); proto =3D htons(ETH_P_ERSPAN2); } else { + reason =3D SKB_DROP_REASON_UNHANDLED_PROTO; goto free_skb; } =20 @@ -764,7 +805,7 @@ static netdev_tx_t erspan_xmit(struct sk_buff *skb, return NETDEV_TX_OK; =20 free_skb: - kfree_skb(skb); + kfree_skb_reason(skb, reason); DEV_STATS_INC(dev, tx_dropped); return NETDEV_TX_OK; } @@ -772,10 +813,12 @@ static netdev_tx_t erspan_xmit(struct sk_buff *skb, static netdev_tx_t gre_tap_xmit(struct sk_buff *skb, struct net_device *dev) { + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; struct ip_tunnel *tunnel =3D netdev_priv(dev); IP_TUNNEL_DECLARE_FLAGS(flags); =20 - if (!pskb_inet_may_pull(skb)) + reason =3D pskb_inet_may_pull_reason(skb); + if (reason) goto free_skb; =20 if (tunnel->collect_md) { @@ -785,17 +828,21 @@ static netdev_tx_t gre_tap_xmit(struct sk_buff *skb, =20 ip_tunnel_flags_copy(flags, tunnel->parms.o_flags); =20 - if (gre_handle_offloads(skb, test_bit(IP_TUNNEL_CSUM_BIT, flags))) + if (gre_handle_offloads(skb, test_bit(IP_TUNNEL_CSUM_BIT, flags))) { + reason =3D SKB_DROP_REASON_NOMEM; goto free_skb; + } =20 - if (skb_cow_head(skb, dev->needed_headroom)) + if (skb_cow_head(skb, dev->needed_headroom)) { + reason =3D SKB_DROP_REASON_NOMEM; goto free_skb; + } =20 __gre_xmit(skb, dev, &tunnel->parms.iph, htons(ETH_P_TEB), flags); return NETDEV_TX_OK; =20 free_skb: - kfree_skb(skb); + kfree_skb_reason(skb, reason); DEV_STATS_INC(dev, tx_dropped); return NETDEV_TX_OK; } --=20 2.47.3 From nobody Fri Sep 25 04:38:26 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 39ED85437C0 for ; Wed, 16 Sep 2026 14:37:36 +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=1789569458; cv=none; b=YSHZ+rwhab0YK9/gBdCp1Yz/EdVY7UVqbkKuqvopWwFcTFe2vX1e7WTViyAJ9miXBoScfV/Akmts6Zm0Ae8fX6RdnjL3xGU5K9k454KybIApwpSoD6ORu/IrZaicAucJJ2edpj3+qf8rW4a3pwwBZscIoiZ444C8tfq0sm+sIPQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789569458; c=relaxed/simple; bh=FYqqj1PmOH7S2LWEsE3Xy6aNF+A4qQjGDxqGjVkO2qQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=JFDJVsr60ALgv4ENSbxV1xYD5QwlHB7hdCCnTQkyW/yyKlOFh4b69olRXb5PHl2tazy3DZuKpFGSQjIynm2yV83acqHrAo1i9ge1KLelcr20DtNnZVtV41rtrZcZkbnTB/rLcKe5FQ014Q/FeWf0Zzqczs2hNNn3ohau/thDpFc= 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=MQrf2q8A; 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="MQrf2q8A" Received: by mail-lf2-f12.google.com with SMTP id 2adb3069b0e04-5b5e4f15cfdso1062285e87.3 for ; Wed, 16 Sep 2026 07:37:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789569454; x=1790174254; 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=kmu/RgpBPaO9Nzgyfpg7t1XLITe45Rlmeeh/CoQR4P4=; b=MQrf2q8Ag7Akl8ahAPUtgD+Sct44f/nb9a9r6W9Q0B/9+zDJduabh5uj5JVIBTXFJn 9nv2FW/d5/NpiTGCkFoi47I/sK4uxFiolyAN3nuX8euL9LBEldcroZ1LwsDdLR/zWsOn yisoys6ycIRjKYv+WRY8k3Yacg5l9V1DAUmreN3DbCbDbfhXUZ1niV51kbxvnXbyzdet gEf/79cUkQHlAN10yZz0nEyTZRGrJMeR7DGXyk1KdY3WtF8mMXNYvB2sscVcBjTZn+0y nyDhuk3zruhhX9vP/JcS165xJfozeiOckGQcv3BN+uIPi/CRJVhcLhumPzz/SfB8hFWm 5R+w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789569454; x=1790174254; 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=kmu/RgpBPaO9Nzgyfpg7t1XLITe45Rlmeeh/CoQR4P4=; b=SYu24HyEBBD4XPbZ+Oxua2lu9pb2jMcnjcWUXwUhGCJk/8UXFF9U/p1ILmxa87yAXy M+6I+TEfIIqS2tU8JrFv/dbGo+oJeN7b4eIhYGPfV4HOhwLEsSyvMY6fxDalf2y2NDT+ pUK2IJHpDhD1Hq/ihHo0unFsKfAaDCdKjYIW9fZmHo1TrfSmg28vl/yRFYhZv8n1PTI6 A8RdvkQF17ck7xmw8WVbV48T2EgGKkxw7mEVK69zrV9edpr5uaOv46QxzaCvM/yw2DFD UizUz2/ioli3bSkmViiKxbBp33gXypLbo24pARlj9rMZTEQ5hKNwgy/4OugE61jj4/Kd 9QfA== X-Forwarded-Encrypted: i=1; AKwUvBzuUkt7sFT1oUNP0wTlI3ER6g9BO/g8U8Ge/IOeSwxFLS7CQShsauhfjDBkAl5gyRjWMLbRgjJNbkPRetE=@vger.kernel.org X-Gm-Message-State: AFuF++nipAfl+G4hPGEgRfjPGpOm2dMTRNCQiTK15Apcyoe7cKiWN1GX DjR9D4nE8Bx0fnMpyT99LL7jzFNPdA+fE9lTWmBQRJNyP0m+4xU3vsGc X-Gm-Gg: AYBFou2eaukuACtK0cLkrVbTPNEEasUIJZbXIuknap2UkHu274P77Uu4KuXs54Pj/kw SiuRYoEIPrTE0kakkuI8X09QgzvIess1/58CU5aE7MUbAgx+WhMar5NiXbUeeHfaVnm6sYJTGFT jq1PPDyXEaRcNP32z09Z9EE8beXD0Gp/nGfnCsfz7b2NQ1oPA7AKdy855WPNgpPUkcP8/6AB4Ds hZVKUWM1QDRxd9JB8wfJ9yDduKuPikuWkXnGZTLsPzL895YsEMRipAuQhrro4QzJXgFdrZRv5cq kxeV/M6NNOqvVKUwITWrCJG3Cz/45GYNRLy0Hk7ppsVTzAvScTe0nopJTdbeUjVxAd8w7ksUFae dkej1VUie1vm5SycVeyU3zbiRPUgM7ATl6xZMLB7ocGT/uB7PlDAH3gvjrIammNZHFtMfve0hS/ xr6NFerQ1IeK5MgufRKRvqfIdxMxdmFCGJ/0VRqw/SHQtGICuYOUx3Sv9BYOnkfQHTAJdTvW98Q CJ47lEPH/8QNZO3rHCGQ0OkGUcWxGvKmPPCXDtm7IAhInrML+Vn2lXQNp4M5R/a X-Received: by 2002:a05:6512:2511:b0:5b6:1a7c:59cd with SMTP id 2adb3069b0e04-5b8b6643b77mr897687e87.39.1789569454155; Wed, 16 Sep 2026 07:37:34 -0700 (PDT) Received: from dau-home-pc.megasoftware.org ([95.139.134.117]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b8b57eb908sm955658e87.79.2026.09.16.07.37.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Sep 2026 07:37:33 -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 v3 8/9] ip6_gre: make prepare_ip6gre_xmit_other() void Date: Wed, 16 Sep 2026 17:37:16 +0300 Message-ID: <20260916143717.1875082-9-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260916143717.1875082-1-littlesmilingcloud@gmail.com> References: <20260916143717.1875082-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 tunnel encapsulation limit option leaves no room for another header, it has nothing to fail on: its only return statement is "return 0", and it has been that way since the function was added by commit 41337f52b967 ("ip6_gre: set DSCP for non-IP"). 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 0b270f4ac774..e7d0fe4570e4 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -693,10 +693,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 @@ -716,8 +716,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) @@ -878,9 +876,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 Fri Sep 25 04:38:26 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 A7CC1545D84 for ; Wed, 16 Sep 2026 14:37:37 +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=1789569461; cv=none; b=sUPrA/B6ECHtt4p7683fNq66wwUStkMo5+2IAlXOi26tX32NNhMHGEo6eh5qSrQ5H/BWuh/qRkw/4z8sRA5gBeveeFR91yQGdbmlkz9kjYfSbqt5GGVh4/MTG+YCk3VOUMY9R3s3lTelyWRQqGm0J1MoDDNZhvMClUd238/3BdI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789569461; c=relaxed/simple; bh=wzMJwr7vwj7fyp5/ozxaTgEEXZlDlvzCoCSY2RuVpwE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=JvI/awhhwuvIT2NlCNbCI0cg89sOgSidro7VYO+hE2YNP3izSoYdgPF9jszjUG+3ENblvV6P5YWP7hh7dPD0JC4CF6a3uM3dGSOjnm2XetoE65fKbBEwrMVYryUute1HA5P3Qap8ISwD/zBOpFp3TZAyBM1XPLJWnWqTSGmp314= 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=Ouf4205j; 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="Ouf4205j" Received: by mail-lf2-f13.google.com with SMTP id 2adb3069b0e04-5b74dbc7359so1016245e87.0 for ; Wed, 16 Sep 2026 07:37:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789569455; x=1790174255; 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=d0EV0wcLkBkaEZAfaLr+N3zrAJ6EtveBgogdeq9Q8LM=; b=Ouf4205jj+vMbs6y5tft5UkQIPMRng0P0lujmGOCwfnKA67yEBwMIid52pOm58caOX gAc0K4yaEQXTaeSwTNkn3zYc3cnrjjoTFFPdg7EsG7oUILyrdI5GZYcRIlvubfhjIRvA gvv2BBpd2Jv/7OOyL9lWmOg5DDQxlnDmeRikCn0AQidqG/3wTIHtIiupr4Mt/iIkjgNJ ZMjHvPLh/dJbx1UydfT19qbfU0JDV0BTAknhcYTdsLHiucp6lFmh2YBJCtKATCMtCBaP 7M7jVI9Imgq4UbOTSD+meX4L8RbHcH93j7QTQWu/Cs6iO+kfHAlT69hvFPFYhU+L9ANm CtwQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789569455; x=1790174255; 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=d0EV0wcLkBkaEZAfaLr+N3zrAJ6EtveBgogdeq9Q8LM=; b=yCVhmliGsuvL+zXPdxTiC7RjiIUPTC6PHMXvgmNdNbxGssWniar1CWiVTPjJwSX4+l q5kY1pkaqkfiMrUr+q9QQTQQYzWEkG/GFRF5S7amDjbEM8dij5ru425G2bDbu8wXKhnf PbyugApdB/Ag587HAlGWazm/S9I/uunOCMo3CYej98+EX8d22qUuAMSwfINuZPcnQ5+d 4ldl3rPRPFSIrmsZ6L2TwcuSut6RysqiZcR1DSTd9nrcn561XcDE5vSU7Vlx6yoPsNyD 8gkdPKCLomOGdQbzYBaI3rxjjxVNAu2GCttDKurhmBBDhMkEaYvA0m9JuyfNuSTlrcKh TPcA== X-Forwarded-Encrypted: i=1; AKwUvByLy5t6ADvFieFw3yr2oSRYkRQYXG4uRam8el+0e7wr8jscpEJKikZRjx3FyN5GjfboU7+orP4GXWSgxAQ=@vger.kernel.org X-Gm-Message-State: AFuF++nw2rpnvffbtir8066lEIrqYozcQRSlBRKP1OuZbkuZ1pO27A/v WkhA9w6fNy2zm5i5DzdOUcWUQvkxPImEvM5bo6kQtfMwWrPqkThenCfM X-Gm-Gg: AYBFou3yDawJK975yF+zosO9oKYPOBTYCoVnVaFUhWFKHFzx1ezESsry2vBcz4M4pKT eXfJcsmwK3Fds8BXhQ7huLmC3QIFeruNPHuSSUzQzksH5fm46o0lMAuGXIk/dEcDZL91U5kgaqp 2uVAYM00SQPjiESTsbmClwNf8O70OZ4xPKU7ksGi1yZ1rLn2kcthHJErF/ZgpFiq4Ao9EQkStT9 3RNKSkxLNpk54UHFrRyW6BeEQ8B0855LGjU/wKe4IhPo/FAFsqV//uqVG1LKHGcmeTYxs31xcwN DJ3QskX+hKThvLsE31//kH/ZT7dBblYVXNNtC/w6Zkg4gqctGFcbT77JYI+tY7AOWltamFjni2/ OMkDPKSW+RFyYpQzqkhZYBBI/Tx9Vbpd/J1Hx9Yt0tLQIIN6/86ilixZq31Q5zyPwHs8VGkc+zH esp/FwVvPu3sI0EhUJemdSguF9zPw3yd+vQyCDwGbYMgBZXw8wA0YOm7MNYaww1a+nAQ+UUa/PO 9eEGgA1h7Nv3AiWEhrTqP/RnkPERl1obEfbsKxFP85xsVtzf4Aw7U7q7hLufmNh X-Received: by 2002:a05:6512:230c:b0:5b6:1a7c:59cf with SMTP id 2adb3069b0e04-5b8b6643babmr898859e87.41.1789569455352; Wed, 16 Sep 2026 07:37:35 -0700 (PDT) Received: from dau-home-pc.megasoftware.org ([95.139.134.117]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b8b57eb908sm955658e87.79.2026.09.16.07.37.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Sep 2026 07:37: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 v3 9/9] ip6_tunnel: add drop reasons to the transmit path Date: Wed, 16 Sep 2026 17:37:17 +0300 Message-ID: <20260916143717.1875082-10-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260916143717.1875082-1-littlesmilingcloud@gmail.com> References: <20260916143717.1875082-1-littlesmilingcloud@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Do for the IPv6 tunnels what the previous patches did for the IPv4 ones. The situation is the same, with one difference: ip6_tnl_xmit() does not free the packet itself, it returns an error and the callers do, so the reason has to travel with it. Give it an output parameter, threaded through ipxip6_tnl_xmit(), __gre6_xmit() and the three ip6gre_xmit_*() helpers, so that the three ndo_start_xmit handlers, where the packet is actually freed, can report it. ip6_gre is converted in the same patch because it calls ip6_tnl_xmit() and would not build otherwise. The reasons are the ones already used on the IPv4 side: - SKB_DROP_REASON_PKT_TOO_BIG for a packet that exceeds the path MTU, - SKB_DROP_REASON_IP_OUTNOROUTES for the route lookups, including the source address selection that a collect_md tunnel has to do when its metadata carries 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 tunnel encapsulation limit option leaves no room for another header. Assisted-by: Claude-Code:claude-opus-5 Signed-off-by: Anton Danilov --- include/net/ip6_tunnel.h | 3 +- net/ipv6/ip6_gre.c | 117 +++++++++++++++++++++++++++------------ net/ipv6/ip6_tunnel.c | 72 +++++++++++++++++------- 3 files changed, 138 insertions(+), 54 deletions(-) diff --git a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h index b99805ee2fd1..95f6d12254df 100644 --- a/include/net/ip6_tunnel.h +++ b/include/net/ip6_tunnel.h @@ -143,7 +143,8 @@ int ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff = *skb, int ip6_tnl_xmit_ctl(struct ip6_tnl *t, const struct in6_addr *laddr, const struct in6_addr *raddr); int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, - struct flowi6 *fl6, int encap_limit, __u32 *pmtu, __u8 proto); + struct flowi6 *fl6, int encap_limit, __u32 *pmtu, __u8 proto, + enum skb_drop_reason *reason); __u16 ip6_tnl_parse_tlv_enc_lim(struct sk_buff *skb, __u8 *raw); __u32 ip6_tnl_get_cap(struct ip6_tnl *t, const struct in6_addr *laddr, const struct in6_addr *raddr); diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index e7d0fe4570e4..5d1e55813fce 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -732,7 +732,8 @@ static struct ip_tunnel_info *skb_tunnel_info_txcheck(s= truct sk_buff *skb) static netdev_tx_t __gre6_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, struct flowi6 *fl6, int encap_limit, - __u32 *pmtu, __be16 proto) + __u32 *pmtu, __be16 proto, + enum skb_drop_reason *reason) { struct ip6_tnl *tunnel =3D netdev_priv(dev); IP_TUNNEL_DECLARE_FLAGS(flags); @@ -756,8 +757,10 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb, =20 tun_info =3D skb_tunnel_info_txcheck(skb); if (IS_ERR(tun_info) || - unlikely(ip_tunnel_info_af(tun_info) !=3D AF_INET6)) + unlikely(ip_tunnel_info_af(tun_info) !=3D AF_INET6)) { + *reason =3D SKB_DROP_REASON_TUNNEL_TXINFO; return -EINVAL; + } =20 key =3D &tun_info->key; memset(fl6, 0, sizeof(*fl6)); @@ -775,8 +778,11 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb, ip_tunnel_flags_and(flags, flags, key->tun_flags); tun_hlen =3D gre_calc_hlen(flags); =20 - if (skb_cow_head(skb, dev->needed_headroom ?: tun_hlen + tunnel->encap_h= len)) + if (skb_cow_head(skb, dev->needed_headroom ?: + tun_hlen + tunnel->encap_hlen)) { + *reason =3D SKB_DROP_REASON_NOMEM; return -ENOMEM; + } =20 gre_build_header(skb, tun_hlen, flags, protocol, @@ -786,8 +792,10 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb, 0); =20 } else { - if (skb_cow_head(skb, dev->needed_headroom ?: tunnel->hlen)) + if (skb_cow_head(skb, dev->needed_headroom ?: tunnel->hlen)) { + *reason =3D SKB_DROP_REASON_NOMEM; return -ENOMEM; + } =20 ip_tunnel_flags_copy(flags, tunnel->parms.o_flags); =20 @@ -799,10 +807,11 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb, } =20 return ip6_tnl_xmit(skb, dev, dsfield, fl6, encap_limit, pmtu, - NEXTHDR_GRE); + NEXTHDR_GRE, reason); } =20 -static inline int ip6gre_xmit_ipv4(struct sk_buff *skb, struct net_device = *dev) +static inline int ip6gre_xmit_ipv4(struct sk_buff *skb, struct net_device = *dev, + enum skb_drop_reason *reason) { struct ip6_tnl *t =3D netdev_priv(dev); int encap_limit =3D -1; @@ -819,11 +828,13 @@ static inline int ip6gre_xmit_ipv4(struct sk_buff *sk= b, struct net_device *dev) =20 err =3D gre_handle_offloads(skb, test_bit(IP_TUNNEL_CSUM_BIT, t->parms.o_flags)); - if (err) + if (err) { + *reason =3D SKB_DROP_REASON_NOMEM; return -1; + } =20 err =3D __gre6_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu, - skb->protocol); + skb->protocol, reason); if (err !=3D 0) { /* XXX: send ICMP error even if DF is not set. */ if (err =3D=3D -EMSGSIZE) @@ -835,7 +846,8 @@ static inline int ip6gre_xmit_ipv4(struct sk_buff *skb,= struct net_device *dev) return 0; } =20 -static inline int ip6gre_xmit_ipv6(struct sk_buff *skb, struct net_device = *dev) +static inline int ip6gre_xmit_ipv6(struct sk_buff *skb, struct net_device = *dev, + enum skb_drop_reason *reason) { struct ip6_tnl *t =3D netdev_priv(dev); struct ipv6hdr *ipv6h =3D ipv6_hdr(skb); @@ -845,19 +857,25 @@ static inline int ip6gre_xmit_ipv6(struct sk_buff *sk= b, struct net_device *dev) __u32 mtu; int err; =20 - if (ipv6_addr_equal(&t->parms.raddr, &ipv6h->saddr)) + if (ipv6_addr_equal(&t->parms.raddr, &ipv6h->saddr)) { + *reason =3D SKB_DROP_REASON_RECURSION_LIMIT; return -1; + } =20 if (!t->parms.collect_md && - prepare_ip6gre_xmit_ipv6(skb, dev, &fl6, &dsfield, &encap_limit)) + prepare_ip6gre_xmit_ipv6(skb, dev, &fl6, &dsfield, &encap_limit)) { + *reason =3D SKB_DROP_REASON_IPV6_BAD_EXTHDR; return -1; + } =20 if (gre_handle_offloads(skb, test_bit(IP_TUNNEL_CSUM_BIT, - t->parms.o_flags))) + t->parms.o_flags))) { + *reason =3D SKB_DROP_REASON_NOMEM; return -1; + } =20 err =3D __gre6_xmit(skb, dev, dsfield, &fl6, encap_limit, - &mtu, skb->protocol); + &mtu, skb->protocol, reason); if (err !=3D 0) { if (err =3D=3D -EMSGSIZE) icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); @@ -867,7 +885,8 @@ static inline int ip6gre_xmit_ipv6(struct sk_buff *skb,= struct net_device *dev) return 0; } =20 -static int ip6gre_xmit_other(struct sk_buff *skb, struct net_device *dev) +static int ip6gre_xmit_other(struct sk_buff *skb, struct net_device *dev, + enum skb_drop_reason *reason) { struct ip6_tnl *t =3D netdev_priv(dev); int encap_limit =3D -1; @@ -882,9 +901,12 @@ static int ip6gre_xmit_other(struct sk_buff *skb, stru= ct net_device *dev) =20 err =3D gre_handle_offloads(skb, test_bit(IP_TUNNEL_CSUM_BIT, t->parms.o_flags)); - if (err) + if (err) { + *reason =3D SKB_DROP_REASON_NOMEM; return err; - err =3D __gre6_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu, skb->prot= ocol); + } + err =3D __gre6_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu, + skb->protocol, reason); =20 return err; } @@ -892,16 +914,20 @@ static int ip6gre_xmit_other(struct sk_buff *skb, str= uct net_device *dev) static netdev_tx_t ip6gre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) { + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; struct ip_tunnel_info *tun_info =3D NULL; struct ip6_tnl *t =3D netdev_priv(dev); __be16 payload_protocol; int ret; =20 - if (!pskb_inet_may_pull(skb)) + reason =3D pskb_inet_may_pull_reason(skb); + if (reason) goto tx_err; =20 - if (!ip6_tnl_xmit_ctl(t, &t->parms.laddr, &t->parms.raddr)) + if (!ip6_tnl_xmit_ctl(t, &t->parms.laddr, &t->parms.raddr)) { + reason =3D SKB_DROP_REASON_DEV_READY; goto tx_err; + } =20 if (t->parms.collect_md) tun_info =3D skb_tunnel_info_txcheck(skb); @@ -909,13 +935,13 @@ static netdev_tx_t ip6gre_tunnel_xmit(struct sk_buff = *skb, payload_protocol =3D skb_protocol(skb, true); switch (payload_protocol) { case htons(ETH_P_IP): - ret =3D ip6gre_xmit_ipv4(skb, dev); + ret =3D ip6gre_xmit_ipv4(skb, dev, &reason); break; case htons(ETH_P_IPV6): - ret =3D ip6gre_xmit_ipv6(skb, dev); + ret =3D ip6gre_xmit_ipv6(skb, dev, &reason); break; default: - ret =3D ip6gre_xmit_other(skb, dev); + ret =3D ip6gre_xmit_other(skb, dev, &reason); break; } =20 @@ -928,13 +954,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); @@ -948,18 +975,25 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_bu= ff *skb, __u32 mtu; int nhoff; =20 - if (!pskb_inet_may_pull(skb)) + reason =3D pskb_inet_may_pull_reason(skb); + if (reason) goto tx_err; =20 - if (!ip6_tnl_xmit_ctl(t, &t->parms.laddr, &t->parms.raddr)) + if (!ip6_tnl_xmit_ctl(t, &t->parms.laddr, &t->parms.raddr)) { + reason =3D SKB_DROP_REASON_DEV_READY; goto tx_err; + } =20 - if (gre_handle_offloads(skb, false)) + if (gre_handle_offloads(skb, false)) { + reason =3D SKB_DROP_REASON_NOMEM; goto tx_err; + } =20 if (skb->len > dev->mtu + dev->hard_header_len) { - if (pskb_trim(skb, dev->mtu + dev->hard_header_len)) + if (pskb_trim(skb, dev->mtu + dev->hard_header_len)) { + reason =3D SKB_DROP_REASON_NOMEM; goto tx_err; + } truncate =3D true; } =20 @@ -979,8 +1013,10 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_bu= ff *skb, truncate =3D true; } =20 - if (skb_cow_head(skb, dev->needed_headroom ?: t->hlen)) + if (skb_cow_head(skb, dev->needed_headroom ?: t->hlen)) { + reason =3D SKB_DROP_REASON_NOMEM; goto tx_err; + } =20 IPCB(skb)->flags =3D 0; =20 @@ -994,8 +1030,10 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_bu= ff *skb, =20 tun_info =3D skb_tunnel_info_txcheck(skb); if (IS_ERR(tun_info) || - unlikely(ip_tunnel_info_af(tun_info) !=3D AF_INET6)) + unlikely(ip_tunnel_info_af(tun_info) !=3D AF_INET6)) { + reason =3D SKB_DROP_REASON_TUNNEL_TXINFO; goto tx_err; + } =20 key =3D &tun_info->key; memset(&fl6, 0, sizeof(fl6)); @@ -1007,10 +1045,14 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_= buff *skb, =20 dsfield =3D key->tos; if (!test_bit(IP_TUNNEL_ERSPAN_OPT_BIT, - tun_info->key.tun_flags)) + tun_info->key.tun_flags)) { + reason =3D SKB_DROP_REASON_TUNNEL_TXINFO; goto tx_err; - if (tun_info->options_len < sizeof(*md)) + } + if (tun_info->options_len < sizeof(*md)) { + reason =3D SKB_DROP_REASON_TUNNEL_TXINFO; goto tx_err; + } md =3D ip_tunnel_info_opts(tun_info); =20 tun_id =3D tunnel_id_to_key32(key->tun_id); @@ -1028,6 +1070,7 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_bu= ff *skb, truncate, false); proto =3D htons(ETH_P_ERSPAN2); } else { + reason =3D SKB_DROP_REASON_UNHANDLED_PROTO; goto tx_err; } } else { @@ -1038,11 +1081,16 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_= buff *skb, &dsfield, &encap_limit); break; case htons(ETH_P_IPV6): - if (ipv6_addr_equal(&t->parms.raddr, &ipv6_hdr(skb)->saddr)) + if (ipv6_addr_equal(&t->parms.raddr, + &ipv6_hdr(skb)->saddr)) { + reason =3D SKB_DROP_REASON_RECURSION_LIMIT; goto tx_err; + } if (prepare_ip6gre_xmit_ipv6(skb, dev, &fl6, - &dsfield, &encap_limit)) + &dsfield, &encap_limit)) { + reason =3D SKB_DROP_REASON_IPV6_BAD_EXTHDR; goto tx_err; + } break; default: memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6)); @@ -1061,6 +1109,7 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_bu= ff *skb, truncate, false); proto =3D htons(ETH_P_ERSPAN2); } else { + reason =3D SKB_DROP_REASON_UNHANDLED_PROTO; goto tx_err; } =20 @@ -1079,7 +1128,7 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_bu= ff *skb, dst->ops->update_pmtu(dst, NULL, skb, mtu, false); } err =3D ip6_tnl_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu, - NEXTHDR_GRE); + NEXTHDR_GRE, &reason); if (err !=3D 0) { /* XXX: send ICMP error even if DF is not set. */ if (err =3D=3D -EMSGSIZE) { @@ -1098,7 +1147,7 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_bu= ff *skb, if (!IS_ERR(tun_info)) DEV_STATS_INC(dev, tx_errors); DEV_STATS_INC(dev, tx_dropped); - kfree_skb(skb); + kfree_skb_reason(skb, reason); return NETDEV_TX_OK; } =20 diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 458ce328311b..138151ed5797 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -1097,6 +1097,7 @@ EXPORT_SYMBOL_GPL(ip6_tnl_xmit_ctl); * @encap_limit: encapsulation limit * @pmtu: Path MTU is stored if packet is too big * @proto: next header value + * @reason: drop reason, only written when the packet is dropped * * Description: * Build new header and do some sanity checks on the packet before sendi= ng @@ -1110,7 +1111,7 @@ EXPORT_SYMBOL_GPL(ip6_tnl_xmit_ctl); =20 int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, struct flowi6 *fl6, int encap_limit, __u32 *pmtu, - __u8 proto) + __u8 proto, enum skb_drop_reason *reason) { struct ip6_tnl *t =3D netdev_priv(dev); struct net *net =3D t->net; @@ -1143,13 +1144,17 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_de= vice *dev, __u8 dsfield, struct neighbour *neigh; int addr_type; =20 - if (!skb_dst(skb)) + if (!skb_dst(skb)) { + *reason =3D SKB_DROP_REASON_NO_TX_TARGET; goto tx_err_link_failure; + } =20 neigh =3D dst_neigh_lookup(skb_dst(skb), &ipv6_hdr(skb)->daddr); - if (!neigh) + if (!neigh) { + *reason =3D SKB_DROP_REASON_NEIGH_CREATEFAIL; goto tx_err_link_failure; + } =20 addr6 =3D (struct in6_addr *)&neigh->primary_key; addr_type =3D ipv6_addr_type(addr6); @@ -1162,8 +1167,10 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_dev= ice *dev, __u8 dsfield, } else if (payload_protocol =3D=3D htons(ETH_P_IP)) { const struct rtable *rt =3D skb_rtable(skb); =20 - if (!rt) + if (!rt) { + *reason =3D SKB_DROP_REASON_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 +1187,10 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_dev= ice *dev, __u8 dsfield, if (use_cache) dst =3D dst_cache_get(&t->dst_cache); =20 - if (!ip6_tnl_xmit_ctl(t, &fl6->saddr, &fl6->daddr)) + if (!ip6_tnl_xmit_ctl(t, &fl6->saddr, &fl6->daddr)) { + *reason =3D SKB_DROP_REASON_DEV_READY; goto tx_err_link_failure; + } =20 if (!dst) { route_lookup: @@ -1190,18 +1199,23 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_de= vice *dev, __u8 dsfield, =20 dst =3D ip6_route_output(net, NULL, fl6); =20 - if (dst->error) + if (dst->error) { + *reason =3D SKB_DROP_REASON_IP_OUTNOROUTES; goto tx_err_link_failure; + } dst =3D xfrm_lookup(net, dst, flowi6_to_flowi(fl6), NULL, 0); if (IS_ERR(dst)) { err =3D PTR_ERR(dst); dst =3D NULL; + *reason =3D SKB_DROP_REASON_IP_OUTNOROUTES; goto tx_err_link_failure; } if (t->parms.collect_md && ipv6_addr_any(&fl6->saddr) && ipv6_dev_get_saddr(net, ip6_dst_idev(dst)->dev, - &fl6->daddr, 0, &fl6->saddr)) + &fl6->daddr, 0, &fl6->saddr)) { + *reason =3D SKB_DROP_REASON_IP_OUTNOROUTES; goto tx_err_link_failure; + } ndst =3D dst; } =20 @@ -1211,6 +1225,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_devi= ce *dev, __u8 dsfield, DEV_STATS_INC(dev, collisions); net_warn_ratelimited("%s: Local routing loop detected!\n", t->parms.name); + *reason =3D SKB_DROP_REASON_RECURSION_LIMIT; goto tx_err_dst_release; } mtu =3D dst6_mtu(dst) - eth_hlen - psh_hlen - t->tun_hlen; @@ -1225,6 +1240,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_devi= ce *dev, __u8 dsfield, if (skb->len - t->tun_hlen - eth_hlen > mtu && !skb_is_gso(skb)) { *pmtu =3D mtu; err =3D -EMSGSIZE; + *reason =3D SKB_DROP_REASON_PKT_TOO_BIG; goto tx_err_dst_release; } =20 @@ -1247,12 +1263,16 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_de= vice *dev, __u8 dsfield, */ max_headroom +=3D LL_RESERVED_SPACE(tdev); =20 - if (skb_cow_head(skb, max_headroom)) + if (skb_cow_head(skb, max_headroom)) { + *reason =3D SKB_DROP_REASON_NOMEM; goto tx_err_dst_release; + } =20 if (t->parms.collect_md) { - if (t->encap.type !=3D TUNNEL_ENCAP_NONE) + if (t->encap.type !=3D TUNNEL_ENCAP_NONE) { + *reason =3D SKB_DROP_REASON_TNL_ENCAP; goto tx_err_dst_release; + } } else { if (use_cache && ndst) dst_cache_set_ip6(&t->dst_cache, ndst, &fl6->saddr); @@ -1276,8 +1296,10 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_dev= ice *dev, __u8 dsfield, ip_tunnel_adj_headroom(dev, max_headroom); =20 err =3D ip6_tnl_encap(skb, t, &proto, fl6); - if (err) + if (err) { + *reason =3D SKB_DROP_REASON_TNL_ENCAP; return err; + } =20 if (encap_limit >=3D 0) { init_tel_txopt(&opt, encap_limit); @@ -1306,7 +1328,7 @@ EXPORT_SYMBOL(ip6_tnl_xmit); =20 static inline int ipxip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, - u8 protocol) + u8 protocol, enum skb_drop_reason *reason) { struct ip6_tnl *t =3D netdev_priv(dev); struct ipv6hdr *ipv6h; @@ -1320,8 +1342,10 @@ ipxip6_tnl_xmit(struct sk_buff *skb, struct net_devi= ce *dev, int err; =20 tproto =3D READ_ONCE(t->parms.proto); - if (tproto !=3D protocol && tproto !=3D 0) + if (tproto !=3D protocol && tproto !=3D 0) { + *reason =3D SKB_DROP_REASON_UNHANDLED_PROTO; return -1; + } =20 if (t->parms.collect_md) { struct ip_tunnel_info *tun_info; @@ -1329,8 +1353,10 @@ ipxip6_tnl_xmit(struct sk_buff *skb, struct net_devi= ce *dev, =20 tun_info =3D skb_tunnel_info(skb); if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX) || - ip_tunnel_info_af(tun_info) !=3D AF_INET6)) + ip_tunnel_info_af(tun_info) !=3D AF_INET6)) { + *reason =3D SKB_DROP_REASON_TUNNEL_TXINFO; return -1; + } key =3D &tun_info->key; memset(&fl6, 0, sizeof(fl6)); fl6.flowi6_proto =3D protocol; @@ -1367,6 +1393,7 @@ ipxip6_tnl_xmit(struct sk_buff *skb, struct net_devic= e *dev, if (tel->encap_limit =3D=3D 0) { icmpv6_ndo_send(skb, ICMPV6_PARAMPROB, ICMPV6_HDR_FIELD, offset + 2); + *reason =3D SKB_DROP_REASON_IPV6_BAD_EXTHDR; return -1; } encap_limit =3D tel->encap_limit - 1; @@ -1408,13 +1435,15 @@ ipxip6_tnl_xmit(struct sk_buff *skb, struct net_dev= ice *dev, fl6.flowi6_uid =3D sock_net_uid(dev_net(dev), NULL); dsfield =3D INET_ECN_encapsulate(dsfield, orig_dsfield); =20 - if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6)) + if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6)) { + *reason =3D SKB_DROP_REASON_NOMEM; return -1; + } =20 skb_set_inner_ipproto(skb, protocol); =20 err =3D ip6_tnl_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu, - protocol); + protocol, reason); if (err !=3D 0) { /* XXX: send ICMP error even if DF is not set. */ if (err =3D=3D -EMSGSIZE) @@ -1438,11 +1467,13 @@ ipxip6_tnl_xmit(struct sk_buff *skb, struct net_dev= ice *dev, static netdev_tx_t ip6_tnl_start_xmit(struct sk_buff *skb, struct net_device *dev) { + enum skb_drop_reason reason =3D SKB_DROP_REASON_NOT_SPECIFIED; struct ip6_tnl *t =3D netdev_priv(dev); u8 ipproto; int ret; =20 - if (!pskb_inet_may_pull(skb)) + reason =3D pskb_inet_may_pull_reason(skb); + if (reason) goto tx_err; =20 switch (skb->protocol) { @@ -1450,18 +1481,21 @@ ip6_tnl_start_xmit(struct sk_buff *skb, struct net_= device *dev) ipproto =3D IPPROTO_IPIP; break; case htons(ETH_P_IPV6): - if (ip6_tnl_addr_conflict(t, ipv6_hdr(skb))) + if (ip6_tnl_addr_conflict(t, ipv6_hdr(skb))) { + reason =3D SKB_DROP_REASON_RECURSION_LIMIT; goto tx_err; + } ipproto =3D IPPROTO_IPV6; break; case htons(ETH_P_MPLS_UC): ipproto =3D IPPROTO_MPLS; break; default: + reason =3D SKB_DROP_REASON_UNHANDLED_PROTO; goto tx_err; } =20 - ret =3D ipxip6_tnl_xmit(skb, dev, ipproto); + ret =3D ipxip6_tnl_xmit(skb, dev, ipproto, &reason); if (ret < 0) goto tx_err; =20 @@ -1470,7 +1504,7 @@ ip6_tnl_start_xmit(struct sk_buff *skb, struct net_de= vice *dev) tx_err: DEV_STATS_INC(dev, tx_errors); DEV_STATS_INC(dev, tx_dropped); - kfree_skb(skb); + kfree_skb_reason(skb, reason); return NETDEV_TX_OK; } =20 --=20 2.47.3