lkml.org 
[lkml]   [2021]   [May]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.10 380/530] udp: never accept GSO_FRAGLIST packets
    Date
    From: Paolo Abeni <pabeni@redhat.com>

    [ Upstream commit 78352f73dc5047f3f744764cc45912498c52f3c9 ]

    Currently the UDP protocol delivers GSO_FRAGLIST packets to
    the sockets without the expected segmentation.

    This change addresses the issue introducing and maintaining
    a couple of new fields to explicitly accept SKB_GSO_UDP_L4
    or GSO_FRAGLIST packets. Additionally updates udp_unexpected_gso()
    accordingly.

    UDP sockets enabling UDP_GRO stil keep accept_udp_fraglist
    zeroed.

    v1 -> v2:
    - use 2 bits instead of a whole GSO bitmask (Willem)

    Fixes: 9fd1ff5d2ac7 ("udp: Support UDP fraglist GRO/GSO.")
    Signed-off-by: Paolo Abeni <pabeni@redhat.com>
    Reviewed-by: Willem de Bruijn <willemb@google.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    include/linux/udp.h | 16 +++++++++++++---
    net/ipv4/udp.c | 3 +++
    2 files changed, 16 insertions(+), 3 deletions(-)

    diff --git a/include/linux/udp.h b/include/linux/udp.h
    index aa84597bdc33..ae58ff3b6b5b 100644
    --- a/include/linux/udp.h
    +++ b/include/linux/udp.h
    @@ -51,7 +51,9 @@ struct udp_sock {
    * different encapsulation layer set
    * this
    */
    - gro_enabled:1; /* Can accept GRO packets */
    + gro_enabled:1, /* Request GRO aggregation */
    + accept_udp_l4:1,
    + accept_udp_fraglist:1;
    /*
    * Following member retains the information to create a UDP header
    * when the socket is uncorked.
    @@ -131,8 +133,16 @@ static inline void udp_cmsg_recv(struct msghdr *msg, struct sock *sk,

    static inline bool udp_unexpected_gso(struct sock *sk, struct sk_buff *skb)
    {
    - return !udp_sk(sk)->gro_enabled && skb_is_gso(skb) &&
    - skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4;
    + if (!skb_is_gso(skb))
    + return false;
    +
    + if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4 && !udp_sk(sk)->accept_udp_l4)
    + return true;
    +
    + if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST && !udp_sk(sk)->accept_udp_fraglist)
    + return true;
    +
    + return false;
    }

    #define udp_portaddr_for_each_entry(__sk, list) \
    diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
    index 4a2fd286787c..9d28b2778e8f 100644
    --- a/net/ipv4/udp.c
    +++ b/net/ipv4/udp.c
    @@ -2657,9 +2657,12 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,

    case UDP_GRO:
    lock_sock(sk);
    +
    + /* when enabling GRO, accept the related GSO packet type */
    if (valbool)
    udp_tunnel_encap_enable(sk->sk_socket);
    up->gro_enabled = valbool;
    + up->accept_udp_l4 = valbool;
    release_sock(sk);
    break;

    --
    2.30.2


    \
     
     \ /
      Last update: 2021-05-12 19:01    [W:9.595 / U:0.028 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site