Commit 45fa29c8 authored by Guillaume Nault's avatar Guillaume Nault Committed by Jakub Kicinski
Browse files

bareudp: Pull inner IP header in bareudp_udp_encap_recv().



Bareudp reads the inner IP header to get the ECN value. Therefore, it
needs to ensure that it's part of the skb's linear data.

This is similar to the vxlan and geneve fixes for that same problem:
  * commit f7789419 ("vxlan: Pull inner IP header in vxlan_rcv().")
  * commit 1ca1ba46 ("geneve: make sure to pull inner header in
    geneve_rx()")

Fixes: 571912c6 ("net: UDP tunnel encapsulation module for tunnelling different protocols like MPLS, IP, NSH etc.")
Signed-off-by: default avatarGuillaume Nault <gnault@redhat.com>
Reviewed-by: default avatarWillem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/5205940067c40218a70fbb888080466b2fc288db.1726046181.git.gnault@redhat.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 5abfdfd4
Loading
Loading
Loading
Loading
+18 −2
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
	__be16 proto;
	void *oiph;
	int err;
	int nh;

	bareudp = rcu_dereference_sk_user_data(sk);
	if (!bareudp)
@@ -148,10 +149,25 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
	}
	skb_dst_set(skb, &tun_dst->dst);
	skb->dev = bareudp->dev;
	oiph = skb_network_header(skb);
	skb_reset_network_header(skb);
	skb_reset_mac_header(skb);

	/* Save offset of outer header relative to skb->head,
	 * because we are going to reset the network header to the inner header
	 * and might change skb->head.
	 */
	nh = skb_network_header(skb) - skb->head;

	skb_reset_network_header(skb);

	if (!pskb_inet_may_pull(skb)) {
		DEV_STATS_INC(bareudp->dev, rx_length_errors);
		DEV_STATS_INC(bareudp->dev, rx_errors);
		goto drop;
	}

	/* Get the outer header. */
	oiph = skb->head + nh;

	if (!ipv6_mod_enabled() || family == AF_INET)
		err = IP_ECN_decapsulate(oiph, skb);
	else