Skip to content

Commit 61761f0

Browse files
Guillaume Naultgregkh
authored andcommitted
bareudp: Pull inner IP header in bareudp_udp_encap_recv().
[ Upstream commit 45fa29c ] 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> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent a4a70cb commit 61761f0

File tree

1 file changed

+18
-2
lines changed

1 file changed

+18
-2
lines changed

drivers/net/bareudp.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
6767
__be16 proto;
6868
void *oiph;
6969
int err;
70+
int nh;
7071

7172
bareudp = rcu_dereference_sk_user_data(sk);
7273
if (!bareudp)
@@ -144,10 +145,25 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
144145
}
145146
skb_dst_set(skb, &tun_dst->dst);
146147
skb->dev = bareudp->dev;
147-
oiph = skb_network_header(skb);
148-
skb_reset_network_header(skb);
149148
skb_reset_mac_header(skb);
150149

150+
/* Save offset of outer header relative to skb->head,
151+
* because we are going to reset the network header to the inner header
152+
* and might change skb->head.
153+
*/
154+
nh = skb_network_header(skb) - skb->head;
155+
156+
skb_reset_network_header(skb);
157+
158+
if (!pskb_inet_may_pull(skb)) {
159+
DEV_STATS_INC(bareudp->dev, rx_length_errors);
160+
DEV_STATS_INC(bareudp->dev, rx_errors);
161+
goto drop;
162+
}
163+
164+
/* Get the outer header. */
165+
oiph = skb->head + nh;
166+
151167
if (!ipv6_mod_enabled() || family == AF_INET)
152168
err = IP_ECN_decapsulate(oiph, skb);
153169
else

0 commit comments

Comments
 (0)