lkml.org 
[lkml]   [2021]   [Apr]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.10 111/188] geneve: do not modify the shared tunnel info when PMTU triggers an ICMP reply
    Date
    From: Antoine Tenart <atenart@kernel.org>

    [ Upstream commit 68c1a943ef37bafde5ea2383e8ca224c7169ee31 ]

    When the interface is part of a bridge or an Open vSwitch port and a
    packet exceed a PMTU estimate, an ICMP reply is sent to the sender. When
    using the external mode (collect metadata) the source and destination
    addresses are reversed, so that Open vSwitch can match the packet
    against an existing (reverse) flow.

    But inverting the source and destination addresses in the shared
    ip_tunnel_info will make following packets of the flow to use a wrong
    destination address (packets will be tunnelled to itself), if the flow
    isn't updated. Which happens with Open vSwitch, until the flow times
    out.

    Fixes this by uncloning the skb's ip_tunnel_info before inverting its
    source and destination addresses, so that the modification will only be
    made for the PTMU packet, not the following ones.

    Fixes: c1a800e88dbf ("geneve: Support for PMTU discovery on directly bridged links")
    Tested-by: Eelco Chaudron <echaudro@redhat.com>
    Reviewed-by: Eelco Chaudron <echaudro@redhat.com>
    Signed-off-by: Antoine Tenart <atenart@kernel.org>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/net/geneve.c | 24 ++++++++++++++++++++----
    1 file changed, 20 insertions(+), 4 deletions(-)

    diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
    index 1426bfc009bc..abd37f26af68 100644
    --- a/drivers/net/geneve.c
    +++ b/drivers/net/geneve.c
    @@ -907,8 +907,16 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,

    info = skb_tunnel_info(skb);
    if (info) {
    - info->key.u.ipv4.dst = fl4.saddr;
    - info->key.u.ipv4.src = fl4.daddr;
    + struct ip_tunnel_info *unclone;
    +
    + unclone = skb_tunnel_info_unclone(skb);
    + if (unlikely(!unclone)) {
    + dst_release(&rt->dst);
    + return -ENOMEM;
    + }
    +
    + unclone->key.u.ipv4.dst = fl4.saddr;
    + unclone->key.u.ipv4.src = fl4.daddr;
    }

    if (!pskb_may_pull(skb, ETH_HLEN)) {
    @@ -992,8 +1000,16 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
    struct ip_tunnel_info *info = skb_tunnel_info(skb);

    if (info) {
    - info->key.u.ipv6.dst = fl6.saddr;
    - info->key.u.ipv6.src = fl6.daddr;
    + struct ip_tunnel_info *unclone;
    +
    + unclone = skb_tunnel_info_unclone(skb);
    + if (unlikely(!unclone)) {
    + dst_release(dst);
    + return -ENOMEM;
    + }
    +
    + unclone->key.u.ipv6.dst = fl6.saddr;
    + unclone->key.u.ipv6.src = fl6.daddr;
    }

    if (!pskb_may_pull(skb, ETH_HLEN)) {
    --
    2.30.2


    \
     
     \ /
      Last update: 2021-04-12 11:41    [W:4.073 / U:0.376 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site