diff options
| author | Anton Danilov <littlesmilingcloud@gmail.com> | 2026-10-05 23:14:15 +0300 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2026-10-07 19:45:43 -0700 |
| commit | 6c0509aa8900134db0ca7de56fc6aa10eac3d026 (patch) | |
| tree | ccb570075374a4d4e8171f9721e82cd6753e6490 /include | |
| parent | 7629d6db839f196f108504662f1ad3b2fa822d0d (diff) | |
ip_tunnel: make __iptunnel_pull_header() return a drop reason
__iptunnel_pull_header() returns -ENOMEM whenever it fails. It can
fail in two pskb_may_pull() calls, one for the tunnel header and one
for the inner Ethernet header of ETH_P_TEB, and in the skb_unclone()
done for GSO packets. pskb_may_pull() fails when the packet is shorter
than the requested length as well as when pulling from the frags cannot
allocate, so a truncated packet and an allocation failure look the same
to the callers. The ones that report a drop reason can only pick
SKB_DROP_REASON_NOMEM, as vxlan_rcv() does, and so would the GRE
receive paths once they report drop reasons. In ip6_gre, gre_rcv()
pulls the header before the tunnel lookup, so a packet from any sender
whose ETH_P_TEB inner Ethernet header or WCCPv2 extra word is cut short
would be reported as an out of memory condition.
Make __iptunnel_pull_header() and iptunnel_pull_header() return the
reason pskb_may_pull_reason() already computes, SKB_DROP_REASON_NOMEM
when skb_unclone() fails, and SKB_NOT_DROPPED_YET on success. A failure
is still non-zero, so the callers that only test the result keep
working. Three callers, in ip_gre and ip6_gre, test it with "< 0"
instead; the enum has no negative values, so that test would always be
false, and the compiler does not warn about it. Make them test for a
non-zero value. vxlan_rcv() keeps reporting NOMEM for any failure until
the next patch has it report the returned reason.
Suggested-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Anton Danilov <littlesmilingcloud@gmail.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20261005201417.906344-3-littlesmilingcloud@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'include')
| -rw-r--r-- | include/net/ip_tunnels.h | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h index 7102aa11fae2..5cccf4c0e691 100644 --- a/include/net/ip_tunnels.h +++ b/include/net/ip_tunnels.h @@ -614,11 +614,13 @@ static inline u8 ip_tunnel_ecn_encap(u8 tos, const struct iphdr *iph, return INET_ECN_encapsulate(tos, inner); } -int __iptunnel_pull_header(struct sk_buff *skb, int hdr_len, - __be16 inner_proto, bool raw_proto, bool xnet); +enum skb_drop_reason +__iptunnel_pull_header(struct sk_buff *skb, int hdr_len, + __be16 inner_proto, bool raw_proto, bool xnet); -static inline int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, - __be16 inner_proto, bool xnet) +static inline enum skb_drop_reason +iptunnel_pull_header(struct sk_buff *skb, int hdr_len, + __be16 inner_proto, bool xnet) { return __iptunnel_pull_header(skb, hdr_len, inner_proto, false, xnet); } |
