From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-lf2-f13.google.com (mail-lf2-f13.google.com [74.125.229.205]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7E2DE522691 for ; Tue, 22 Sep 2026 22:15:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.229.205 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790115352; cv=none; b=RE7mxkkdV70pEISf9sfg0tHmnQ5cW7bZjfI8U00bL+3WF/N4DgAnUWj+78g155Ty5ccsEfR3pFV2uWDZ9inbdS0w35T9lu4XmNdBGfPsqKs8YuqUVnfLUlDQPAAoyYEQ3nhOOMsLf1gC+2zq2f3jyyAV0ssne3pMdi0EGTjzkOY= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790115352; c=relaxed/simple; bh=OW2CuFCCxfYS9SdBfkXjwwy6lIRLZuhaoeGNoJ5XxbY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gD6PpsVHKWK8Zba/Ue4rU57rmDrIwLT7yCBDlhHdcEjk9AWUO9MBnlUPb4o0MJlI0Yzgmq7L6rj0KZeTimIwb0F/hXyc26Kutx5vHru3/bFf0yYvDQRjn3J851pRAPsK7kOqHNvGlqEi3MeGBesgcacuCtzwom8pznpAG1FN87A= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=lpG5Q0Sn; arc=none smtp.client-ip=74.125.229.205 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="lpG5Q0Sn" Received: by mail-lf2-f13.google.com with SMTP id 2adb3069b0e04-5b8c1b8d7b5so265872e87.0 for ; Tue, 22 Sep 2026 15:15:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1790115335; x=1790720135; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=EFYqjKXJT0aHpkGiNFipCh7kFpFVgjGz3iETsztdd8M=; b=lpG5Q0Snj6h+gWT+z9f8RiDWOfiq92gcr7+K/F/9FIzBvyRcEoq7Yi/0eCCQergndt G0YAPRT5FFKr/pRFI+Ptl34yqdl83hAIGhUcm5duCT3dAmROYDt5rGtR/1LDh0IAhr2S fMINOuleFBANuPBjneelGvkb6aYVBE6qwMbLrTX9HMXtDfoA9iQb2jm5Fnen3muaVGQL MwlhUDQVcmL7lB6AcX+Xpuy2V42IFZQVWGLrTL8iSXjwncwQ4aQmnU1BHjvXwHPK/yDO YenTeHWqh31HgyklJ+PVKJRSH2zMDs89WQ6WX1zwbDxtukBsGyl4Elc6upQb+B/E1RkQ qKxg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790115335; x=1790720135; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=EFYqjKXJT0aHpkGiNFipCh7kFpFVgjGz3iETsztdd8M=; b=pzgg/plkHvqceNEu+TFDTtkwPLwLLYEXKTbMYJNQzfW294hLItYCr71Fxk9s6ZWfXV Rz33XX8heUlZCGUgKoK6N68rgkWmFKWLpJI5cKhVwTkaM7LAT3r/IDQX9eV6tu0fXX41 A3aUuydaiGUKhdqinzAIyByPoip39onZBRtfjAA2zbiLmmoaheuxV8OjqE+4bygvxOmk rHZhqzI/bw/jSsqFGppidqCf6zrXBw9l+zDWjx3N+lQWDXZhDzzDYRCFTiUGJ2kV4GKL p9kCOmkS4cDoP7xVhhw++j9aeuIJqHmjwAr+sBWW9VeU2pjRzNYPQN1CSidcnBeq6puF 02Fw== X-Forwarded-Encrypted: i=1; AKwUvBwtPFUqy2bKDYvvpAcA1J+3DUBso7FUpydKTBO46KxXSWrqq5dmbYL+wwPwGQ4WkQ0z15Es3MZrP6EqQ34=@vger.kernel.org X-Gm-Message-State: AFuF++mgt3fPf8VIEwCutnMoxzYxjzX49oCuvqeRiy8PzDWIH3US/gz2 otUoLtYhuKq4gARmn4R2/GWDwcvD98lHJbBSnwKSXw3w4b76ttXwBAHf X-Gm-Gg: AYBFou0zRFo7RKQh9mLQGZx7zLwn/ezv3aA3X0Yxq5p1XerTOA8UnDr5pjq75zJ0Y/g 0WRiNdwWoJoI00AYGSz7+H5mYt4K3VUngbzGL/582NznpUr0vX0LDPCpaseY5IFLRclvGapxbhf Vz/g+wSLLekFAbarM7F8FnHjoisL+RGORCbHUMkT1lDdxlsq6peKwG7kziv+3vhDHHcJvzqWdhm U31f42F7Y0lBvWu8iyuyhVTLd21AumvUGrbaEpcPeYxjkV2mVw+BU9I6Wrmshx4DlvMbcNGocmc isHBzOhmUclqjonOFzEwFELACu57+8c65pdoIMdoJjPJ5WQFoxFNnRGrh+OduHiur33My1Z1hZv xS8rZjaYpuqbugCkVBeR1L5xOhX+lnOCuUWatlYHzF5Qy9E6SRqQtoawuIt8uLO0X0WJGo+B8wr bRzjZufZdA8+1vKKLVCh+PMCZQRvmZC2w8SPZfD4I3wXF6QzxYkM75LTT317t/yk8/WJmWXJ9V4 zRGB4PJUyJcjoyxVI0DVwQQeEQW4M1qeajVNW/RaCSao6Tv+yl6BwLHmB5wEDFwf5HY2vju X-Received: by 2002:a05:6512:61c8:10b0:5b4:ac27:6bb0 with SMTP id 2adb3069b0e04-5b8d897bcb6mr153177e87.25.1790115335072; Tue, 22 Sep 2026 15:15:35 -0700 (PDT) Received: from dau-home-pc.megasoftware.org ([94.28.220.48]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b8d857873asm164920e87.17.2026.09.22.15.15.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Sep 2026 15:15:34 -0700 (PDT) From: Anton Danilov To: netdev@vger.kernel.org Cc: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , David Ahern , Simon Horman , Ido Schimmel , linux-kernel@vger.kernel.org Subject: [PATCH net-next v4 08/10] ip_gre: add drop reasons to the transmit path Date: Wed, 23 Sep 2026 01:15:05 +0300 Message-ID: <20260922221507.3268127-9-littlesmilingcloud@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260922221507.3268127-1-littlesmilingcloud@gmail.com> References: <20260922221507.3268127-1-littlesmilingcloud@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Each transmit function of ip_gre ends all of its failures in one kfree_skb() and a tx_dropped increment, so a drop can be traced to the function and to nothing more precise than "the tunnel did not send it". No new reason is needed. The length helpers already compute one, so pskb_inet_may_pull_reason() and pskb_may_pull_reason() are used instead of their boolean wrappers, and the rest reuses: - SKB_DROP_REASON_NOMEM for the headroom expansions, the offload handling and the trims, - SKB_DROP_REASON_TUNNEL_TXINFO for the collect_md paths, when the metadata is missing or incomplete, - SKB_DROP_REASON_UNHANDLED_PROTO for an ERSPAN version that is not implemented, - SKB_DROP_REASON_SKB_CSUM when the checksum starts before the data the tunnel is about to send. Assisted-by: Claude-Code:claude-opus-5 Signed-off-by: Anton Danilov --- net/ipv4/ip_gre.c | 101 +++++++++++++++++++++++++++++++++------------- 1 file changed, 74 insertions(+), 27 deletions(-) diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index e158d6e9d42a..ad669b3f8757 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -506,6 +506,7 @@ static int gre_handle_offloads(struct sk_buff *skb, bool csum) static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev, __be16 proto) { + enum skb_drop_reason reason = SKB_DROP_REASON_NOT_SPECIFIED; struct ip_tunnel *tunnel = netdev_priv(dev); IP_TUNNEL_DECLARE_FLAGS(flags) = { }; struct ip_tunnel_info *tun_info; @@ -514,19 +515,25 @@ static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev, tun_info = skb_tunnel_info(skb); if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX) || - ip_tunnel_info_af(tun_info) != AF_INET)) + ip_tunnel_info_af(tun_info) != AF_INET)) { + reason = SKB_DROP_REASON_TUNNEL_TXINFO; goto err_free_skb; + } key = &tun_info->key; tunnel_hlen = gre_calc_hlen(key->tun_flags); - if (skb_cow_head(skb, dev->needed_headroom)) + if (skb_cow_head(skb, dev->needed_headroom)) { + reason = SKB_DROP_REASON_NOMEM; goto err_free_skb; + } /* Push Tunnel header. */ if (gre_handle_offloads(skb, test_bit(IP_TUNNEL_CSUM_BIT, - tunnel->parms.o_flags))) + tunnel->parms.o_flags))) { + reason = SKB_DROP_REASON_NOMEM; goto err_free_skb; + } __set_bit(IP_TUNNEL_CSUM_BIT, flags); __set_bit(IP_TUNNEL_KEY_BIT, flags); @@ -543,12 +550,13 @@ static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev, return; err_free_skb: - kfree_skb(skb); + kfree_skb_reason(skb, reason); DEV_STATS_INC(dev, tx_dropped); } static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev) { + enum skb_drop_reason reason = SKB_DROP_REASON_NOT_SPECIFIED; struct ip_tunnel *tunnel = netdev_priv(dev); IP_TUNNEL_DECLARE_FLAGS(flags) = { }; struct ip_tunnel_info *tun_info; @@ -562,29 +570,41 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev) tun_info = skb_tunnel_info(skb); if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX) || - ip_tunnel_info_af(tun_info) != AF_INET)) + ip_tunnel_info_af(tun_info) != AF_INET)) { + reason = SKB_DROP_REASON_TUNNEL_TXINFO; goto err_free_skb; + } key = &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 = SKB_DROP_REASON_TUNNEL_TXINFO; goto err_free_skb; - if (tun_info->options_len < sizeof(*md)) + } + if (tun_info->options_len < sizeof(*md)) { + reason = SKB_DROP_REASON_TUNNEL_TXINFO; goto err_free_skb; + } md = ip_tunnel_info_opts(tun_info); /* ERSPAN has fixed 8 byte GRE header */ version = md->version; tunnel_hlen = 8 + erspan_hdr_len(version); - if (skb_cow_head(skb, dev->needed_headroom)) + if (skb_cow_head(skb, dev->needed_headroom)) { + reason = SKB_DROP_REASON_NOMEM; goto err_free_skb; + } - if (gre_handle_offloads(skb, false)) + if (gre_handle_offloads(skb, false)) { + reason = SKB_DROP_REASON_NOMEM; goto err_free_skb; + } if (skb->len > dev->mtu + dev->hard_header_len) { - if (pskb_trim(skb, dev->mtu + dev->hard_header_len)) + if (pskb_trim(skb, dev->mtu + dev->hard_header_len)) { + reason = SKB_DROP_REASON_NOMEM; goto err_free_skb; + } truncate = true; } @@ -616,6 +636,7 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev) truncate, true); proto = htons(ETH_P_ERSPAN2); } else { + reason = SKB_DROP_REASON_UNHANDLED_PROTO; goto err_free_skb; } @@ -628,7 +649,7 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev) return; err_free_skb: - kfree_skb(skb); + kfree_skb_reason(skb, reason); DEV_STATS_INC(dev, tx_dropped); } @@ -659,11 +680,13 @@ static int gre_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb) static netdev_tx_t ipgre_xmit(struct sk_buff *skb, struct net_device *dev) { + enum skb_drop_reason reason = SKB_DROP_REASON_NOT_SPECIFIED; struct ip_tunnel *tunnel = netdev_priv(dev); IP_TUNNEL_DECLARE_FLAGS(flags); const struct iphdr *tnl_params; - if (!pskb_inet_may_pull(skb)) + reason = pskb_inet_may_pull_reason(skb); + if (reason) goto free_skb; if (tunnel->collect_md) { @@ -674,10 +697,13 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb, if (dev->header_ops) { int pull_len = tunnel->hlen + sizeof(struct iphdr); - if (skb_cow_head(skb, 0)) + if (skb_cow_head(skb, 0)) { + reason = SKB_DROP_REASON_NOMEM; goto free_skb; + } - if (!pskb_may_pull(skb, pull_len)) + reason = pskb_may_pull_reason(skb, pull_len); + if (reason) goto free_skb; tnl_params = (const struct iphdr *)skb->data; @@ -687,25 +713,31 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb, skb_reset_mac_header(skb); if (skb->ip_summed == CHECKSUM_PARTIAL && - skb_checksum_start(skb) < skb->data) + skb_checksum_start(skb) < skb->data) { + reason = 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 = SKB_DROP_REASON_NOMEM; goto free_skb; + } tnl_params = &tunnel->parms.iph; } ip_tunnel_flags_copy(flags, tunnel->parms.o_flags); - 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 = SKB_DROP_REASON_NOMEM; goto free_skb; + } __gre_xmit(skb, dev, tnl_params, skb->protocol, flags); return NETDEV_TX_OK; free_skb: - kfree_skb(skb); + kfree_skb_reason(skb, reason); DEV_STATS_INC(dev, tx_dropped); return NETDEV_TX_OK; } @@ -713,12 +745,14 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb, static netdev_tx_t erspan_xmit(struct sk_buff *skb, struct net_device *dev) { + enum skb_drop_reason reason = SKB_DROP_REASON_NOT_SPECIFIED; struct ip_tunnel *tunnel = netdev_priv(dev); IP_TUNNEL_DECLARE_FLAGS(flags); bool truncate = false; __be16 proto; - if (!pskb_inet_may_pull(skb)) + reason = pskb_inet_may_pull_reason(skb); + if (reason) goto free_skb; if (tunnel->collect_md) { @@ -726,15 +760,21 @@ static netdev_tx_t erspan_xmit(struct sk_buff *skb, return NETDEV_TX_OK; } - if (gre_handle_offloads(skb, false)) + if (gre_handle_offloads(skb, false)) { + reason = SKB_DROP_REASON_NOMEM; goto free_skb; + } - if (skb_cow_head(skb, dev->needed_headroom)) + if (skb_cow_head(skb, dev->needed_headroom)) { + reason = SKB_DROP_REASON_NOMEM; goto free_skb; + } if (skb->len > dev->mtu + dev->hard_header_len) { - if (pskb_trim(skb, dev->mtu + dev->hard_header_len)) + if (pskb_trim(skb, dev->mtu + dev->hard_header_len)) { + reason = SKB_DROP_REASON_NOMEM; goto free_skb; + } truncate = true; } @@ -755,6 +795,7 @@ static netdev_tx_t erspan_xmit(struct sk_buff *skb, truncate, true); proto = htons(ETH_P_ERSPAN2); } else { + reason = SKB_DROP_REASON_UNHANDLED_PROTO; goto free_skb; } @@ -763,7 +804,7 @@ static netdev_tx_t erspan_xmit(struct sk_buff *skb, return NETDEV_TX_OK; free_skb: - kfree_skb(skb); + kfree_skb_reason(skb, reason); DEV_STATS_INC(dev, tx_dropped); return NETDEV_TX_OK; } @@ -771,10 +812,12 @@ static netdev_tx_t erspan_xmit(struct sk_buff *skb, static netdev_tx_t gre_tap_xmit(struct sk_buff *skb, struct net_device *dev) { + enum skb_drop_reason reason = SKB_DROP_REASON_NOT_SPECIFIED; struct ip_tunnel *tunnel = netdev_priv(dev); IP_TUNNEL_DECLARE_FLAGS(flags); - if (!pskb_inet_may_pull(skb)) + reason = pskb_inet_may_pull_reason(skb); + if (reason) goto free_skb; if (tunnel->collect_md) { @@ -784,17 +827,21 @@ static netdev_tx_t gre_tap_xmit(struct sk_buff *skb, ip_tunnel_flags_copy(flags, tunnel->parms.o_flags); - 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 = SKB_DROP_REASON_NOMEM; goto free_skb; + } - if (skb_cow_head(skb, dev->needed_headroom)) + if (skb_cow_head(skb, dev->needed_headroom)) { + reason = SKB_DROP_REASON_NOMEM; goto free_skb; + } __gre_xmit(skb, dev, &tunnel->parms.iph, htons(ETH_P_TEB), flags); return NETDEV_TX_OK; free_skb: - kfree_skb(skb); + kfree_skb_reason(skb, reason); DEV_STATS_INC(dev, tx_dropped); return NETDEV_TX_OK; } -- 2.47.3