Thread (18 messages) flat view 18 messages, 2 authors, 10h ago

Re: [PATCH net-next v4 03/10] gre: make gre_parse_header() report a drop reason

From: Ido Schimmel <idosch@nvidia.com>
Date: 2026-09-23 15:00:07
Also in: lkml

On Wed, Sep 23, 2026 at 01:15:00AM +0300, Anton Danilov wrote:
quoted hunk ↗ jump to hunk
diff --git a/net/ipv4/gre_demux.c b/net/ipv4/gre_demux.c
index 96fd7dc6d82d..e117056525f0 100644
--- a/net/ipv4/gre_demux.c
+++ b/net/ipv4/gre_demux.c
@@ -56,28 +56,35 @@ int gre_del_protocol(const struct gre_protocol *proto, u8 version)
 }
 EXPORT_SYMBOL_GPL(gre_del_protocol);
 
-/* Fills in tpi and returns header length to be pulled.
+/* Fills in tpi, including the header length to be pulled in tpi->hdr_len,
+ * and returns SKB_NOT_DROPPED_YET, or the reason to drop the packet if the
+ * header is rejected.
  * Note that caller must use pskb_may_pull() before pulling GRE header.
+ *
+ * @icmp_err is set by the ICMP error handlers, which only get a part of
+ * the original packet: a checksum failure does not reject the header then,
+ * the checksum is still computed and the rest of the header is parsed.
  */
-int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi,
-		     bool *csum_err, __be16 proto, int nhs)
+enum skb_drop_reason
+gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi,
+		 bool icmp_err, __be16 proto, int nhs)
 {
 	const struct gre_base_hdr *greh;
 	__be32 *options;
 	int hdr_len;
 
 	if (unlikely(!pskb_may_pull(skb, nhs + sizeof(struct gre_base_hdr))))
-		return -EINVAL;
+		return SKB_DROP_REASON_HDR_TRUNC;
Please use pskb_may_pull_reason() as is done throughout the kernel.
AFAICT, there's only one user of HDR_TRUNC (in tun) and it should also
be converted to pskb_may_pull_reason() so that we could remove
HDR_TRUNC. Can you send a patch?
 
 	greh = (struct gre_base_hdr *)(skb->data + nhs);
 	if (unlikely(greh->flags & (GRE_VERSION | GRE_ROUTING)))
-		return -EINVAL;
+		return SKB_DROP_REASON_GRE_INVALID_HDR;
[...]
 static int gre_rcv(struct sk_buff *skb)
 {
+	enum skb_drop_reason reason = SKB_DROP_REASON_NOT_SPECIFIED;
 	const struct gre_protocol *proto;
 	u8 ver;
 	int ret;
 
-	if (!pskb_may_pull(skb, 12))
+	reason = pskb_may_pull_reason(skb, 12);
+	if (reason)
 		goto drop;
 
 	ver = skb->data[1]&0x7f;
-	if (ver >= GREPROTO_MAX)
+	if (ver >= GREPROTO_MAX) {
+		reason = SKB_DROP_REASON_UNHANDLED_PROTO;
This should be TUNNEL_INVALID_HDR to be consistent with the hunk above.
quoted hunk ↗ jump to hunk
 		goto drop;
+	}
 
 	rcu_read_lock();
 	proto = rcu_dereference(gre_proto[ver]);
@@ -167,11 +177,11 @@ static int gre_rcv(struct sk_buff *skb)
 drop_nohandler:
 	rcu_read_unlock();
 	dev_core_stats_rx_nohandler_inc(skb->dev);
-	kfree_skb(skb);
+	kfree_skb_reason(skb, SKB_DROP_REASON_UNHANDLED_PROTO);
This looks correct.
 	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;
 }
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help