Skip to content

Commit

Permalink
bareudp: Pull inner IP header in bareudp_udp_encap_recv().
Browse files Browse the repository at this point in the history
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 f778941 ("vxlan: Pull inner IP header in vxlan_rcv().")
  * commit 1ca1ba4 ("geneve: make sure to pull inner header in
    geneve_rx()")

Fixes: 571912c ("net: UDP tunnel encapsulation module for tunnelling different protocols like MPLS, IP, NSH etc.")
Signed-off-by: Guillaume Nault <gnault@redhat.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/5205940067c40218a70fbb888080466b2fc288db.1726046181.git.gnault@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Guillaume Nault authored and Jakub Kicinski committed Sep 13, 2024
1 parent 5abfdfd commit 45fa29c
Showing 1 changed file with 18 additions and 2 deletions.
20 changes: 18 additions & 2 deletions drivers/net/bareudp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 45fa29c

Please sign in to comment.