lkml.org 
[lkml]   [2017]   [Mar]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.10 36/63] net/tunnel: set inner protocol in network gro hooks
    Date
    4.10-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Paolo Abeni <pabeni@redhat.com>


    [ Upstream commit 294acf1c01bace5cea5d30b510504238bf5f7c25 ]

    The gso code of several tunnels type (gre and udp tunnels)
    takes for granted that the skb->inner_protocol is properly
    initialized and drops the packet elsewhere.

    On the forwarding path no one is initializing such field,
    so gro encapsulated packets are dropped on forward.

    Since commit 38720352412a ("gre: Use inner_proto to obtain
    inner header protocol"), this can be reproduced when the
    encapsulated packets use gre as the tunneling protocol.

    The issue happens also with vxlan and geneve tunnels since
    commit 8bce6d7d0d1e ("udp: Generalize skb_udp_segment"), if the
    forwarding host's ingress nic has h/w offload for such tunnel
    and a vxlan/geneve device is configured on top of it, regardless
    of the configured peer address and vni.

    To address the issue, this change initialize the inner_protocol
    field for encapsulated packets in both ipv4 and ipv6 gro complete
    callbacks.

    Fixes: 38720352412a ("gre: Use inner_proto to obtain inner header protocol")
    Fixes: 8bce6d7d0d1e ("udp: Generalize skb_udp_segment")
    Signed-off-by: Paolo Abeni <pabeni@redhat.com>
    Acked-by: Alexander Duyck <alexander.h.duyck@intel.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    net/ipv4/af_inet.c | 4 +++-
    net/ipv6/ip6_offload.c | 4 +++-
    2 files changed, 6 insertions(+), 2 deletions(-)

    --- a/net/ipv4/af_inet.c
    +++ b/net/ipv4/af_inet.c
    @@ -1470,8 +1470,10 @@ int inet_gro_complete(struct sk_buff *sk
    int proto = iph->protocol;
    int err = -ENOSYS;

    - if (skb->encapsulation)
    + if (skb->encapsulation) {
    + skb_set_inner_protocol(skb, cpu_to_be16(ETH_P_IP));
    skb_set_inner_network_header(skb, nhoff);
    + }

    csum_replace2(&iph->check, iph->tot_len, newlen);
    iph->tot_len = newlen;
    --- a/net/ipv6/ip6_offload.c
    +++ b/net/ipv6/ip6_offload.c
    @@ -294,8 +294,10 @@ static int ipv6_gro_complete(struct sk_b
    struct ipv6hdr *iph = (struct ipv6hdr *)(skb->data + nhoff);
    int err = -ENOSYS;

    - if (skb->encapsulation)
    + if (skb->encapsulation) {
    + skb_set_inner_protocol(skb, cpu_to_be16(ETH_P_IPV6));
    skb_set_inner_network_header(skb, nhoff);
    + }

    iph->payload_len = htons(skb->len - nhoff - sizeof(*iph));


    \
     
     \ /
      Last update: 2017-03-20 19:08    [W:3.030 / U:0.052 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site