udp: never accept GSO_FRAGLIST packets
[ 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: 9fd1ff5d2a
("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>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
c45cb22a55
commit
4877c4a523
@@ -51,7 +51,9 @@ struct udp_sock {
|
|||||||
* different encapsulation layer set
|
* different encapsulation layer set
|
||||||
* this
|
* 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
|
* Following member retains the information to create a UDP header
|
||||||
* when the socket is uncorked.
|
* 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)
|
static inline bool udp_unexpected_gso(struct sock *sk, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
return !udp_sk(sk)->gro_enabled && skb_is_gso(skb) &&
|
if (!skb_is_gso(skb))
|
||||||
skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4;
|
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) \
|
#define udp_portaddr_for_each_entry(__sk, list) \
|
||||||
|
@@ -2657,9 +2657,12 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
|
|||||||
|
|
||||||
case UDP_GRO:
|
case UDP_GRO:
|
||||||
lock_sock(sk);
|
lock_sock(sk);
|
||||||
|
|
||||||
|
/* when enabling GRO, accept the related GSO packet type */
|
||||||
if (valbool)
|
if (valbool)
|
||||||
udp_tunnel_encap_enable(sk->sk_socket);
|
udp_tunnel_encap_enable(sk->sk_socket);
|
||||||
up->gro_enabled = valbool;
|
up->gro_enabled = valbool;
|
||||||
|
up->accept_udp_l4 = valbool;
|
||||||
release_sock(sk);
|
release_sock(sk);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user