From mboxrd@z Thu Jan 1 00:00:00 1970 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 DD4FE530DE6 for ; Tue, 22 Sep 2026 22:15:43 +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=1790115349; cv=none; b=JqmJcnTzMSnDqLFoiviB3lxWCk9LeYmsg4ZC0ri4fhhImY1q9pr3Lge4mAFl9Dw+Q/S4M3g1jplablNxL+BRWCyYu9ctyYlG7wEYzYUzFFNHQy0SABgftu4kQ+hzjpudDhlTh0G2xfRm7/4G0m4HU96j5SjOD2lFMtucbpk3+p4= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790115349; c=relaxed/simple; bh=OW2CuFCCxfYS9SdBfkXjwwy6lIRLZuhaoeGNoJ5XxbY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fMO+PWC9LsRfYUsNfkj6AXJg4BTXW+8plyMK5Zm8m0Tm/vZ5M3K9LIrfvZHL1Dl7iAGHsYGlW+73beMw3XfMWdkySJuNNNsaXdhiJPmqLBPog/92bxWDCVl6s/xRb+EbcMzqkOj8UCBqaxgELD8cWVHuaf3gGbO2yZfLWt+Anrs= 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.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="lpG5Q0Sn" Received: by mail-lf2-f12.google.com with SMTP id 2adb3069b0e04-5b5e4f16f12so212110e87.1 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=MwzQDqaOBci/ENYkBYW9qI7y5Wdi/SUP+ElO0yiXiWzhrHqKCUiStMtVevjZ09WXYm LEcneJfRM0cWBOXYVbHaeMTBglPdpdl5pRfPOcXG7LUE7lq9WR/OW+iOlG4XRtDclV46 BSiDwiD2Xta2EU6+ejE0plcSoZkAfKSORkfNgfuWXN6C2R3C81NEQMdt9Fj5YABZsStb voi3k8xvU+Cam4jFBJg8GBEJSC0HYNr8GwDQOZZiR819kKAuQpwIMF30eMIJVnKZE1jO JBbsAOUCkZjubeZUWCZqEs0BA2OpUCMllU2V7L3VaWP4Aa6s2jcdjHM6S1uyRZK2Ade/ LqXg== X-Gm-Message-State: AFuF++n+NShn+f2D08XfwiSRcL+V/n7q1JznK+UhWvrV9mHBQnw7tbOZ k/iw/Dm7AEEtC0zurkOIY7d5+LRJYzMGuyLwYdG4bwKoks2Uj/N2B7XbhwbCrqwh3eE= X-Gm-Gg: AYBFou3iA2nSSe2kCzbaF07APdEPSQZL8ggngb3Kr/o58jQnWhBj+C+l6WNLPSbIZWB WkHur2ewOlly8pgGIffQwtn1hDSNcPBgaXykpyHHU1o07Db7G6xdnnI9tlwCIQewfm/qUVhnS0w hGMsDoTQx+t7wwBEb8HjUSLg8Pb0PkcW5iTiL95eg0y4S2mEWBQJFwwB8A8Upsj228ZC+tqkP/i wOpXubwmqrZZTH/STALHFUIPu81xPEiGISNmokfiWYFF7Jq8jccwtAwTsQqkmITbLtRebsbHp65 71IKBLMwtzee1LWhgc0+dZqtYkhAb/a6cnpLpQBvNeaUKdsunDMXjd2l4XSzWfLgh2UBl9+lQk0 9NR55YWdspfIWALUtUZ4NoMqacmz3XDgar9Bea+cQZvxhzwyyjStJ+EcHoBa+X3/EW7hoHbYfCm boz8bqaCN0URSP3HHV2teLzB5G1BWnY5MlAoJ/4yIKUQ4HAlXyZ0dqKGE3GL8NI51fWa74aDDPt ll50G50/7ZDVDU60WMuDyvDWzpxzX/CobKVPXDtApzNzBPxSWc48i3DXvF8MzasiuIhLd99 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: netdev@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