mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-29 22:02:02 +00:00
vxlan: Pull inner IP header in vxlan_rcv().
Ensure the inner IP header is part of skb's linear data before reading its ECN bits. Otherwise we might read garbage. One symptom is the system erroneously logging errors like "vxlan: non-ECT from xxx.xxx.xxx.xxx with TOS=xxxx". Similar bugs have been fixed in geneve, ip_tunnel and ip6_tunnel (see commit1ca1ba465e
("geneve: make sure to pull inner header in geneve_rx()") for example). So let's reuse the same code structure for consistency. Maybe we'll can add a common helper in the future. Fixes:d342894c5d
("vxlan: virtual extensible lan") Signed-off-by: Guillaume Nault <gnault@redhat.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org> Reviewed-by: Sabrina Dubroca <sd@queasysnail.net> Link: https://lore.kernel.org/r/1239c8db54efec341dd6455c77e0380f58923a3c.1714495737.git.gnault@redhat.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
97bf6f81b2
commit
f778941913
1 changed files with 18 additions and 1 deletions
|
@ -1674,6 +1674,7 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb)
|
|||
bool raw_proto = false;
|
||||
void *oiph;
|
||||
__be32 vni = 0;
|
||||
int nh;
|
||||
|
||||
/* Need UDP and VXLAN header to be present */
|
||||
if (!pskb_may_pull(skb, VXLAN_HLEN))
|
||||
|
@ -1762,9 +1763,25 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb)
|
|||
skb->pkt_type = PACKET_HOST;
|
||||
}
|
||||
|
||||
oiph = skb_network_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(vxlan->dev, rx_length_errors);
|
||||
DEV_STATS_INC(vxlan->dev, rx_errors);
|
||||
vxlan_vnifilter_count(vxlan, vni, vninode,
|
||||
VXLAN_VNI_STATS_RX_ERRORS, 0);
|
||||
goto drop;
|
||||
}
|
||||
|
||||
/* Get the outer header. */
|
||||
oiph = skb->head + nh;
|
||||
|
||||
if (!vxlan_ecn_decapsulate(vs, oiph, skb)) {
|
||||
DEV_STATS_INC(vxlan->dev, rx_frame_errors);
|
||||
DEV_STATS_INC(vxlan->dev, rx_errors);
|
||||
|
|
Loading…
Reference in a new issue