Message ID | 20240319093140.499123-2-atenart@kernel.org (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | gro: various fixes related to UDP tunnels | expand |
On Tue, 19 Mar 2024 10:31:36 +0100 Antoine Tenart wrote:
> +DECLARE_STATIC_KEY_FALSE(udp_encap_needed_key);
nit: our build bot says you need to export this as well for v6=m.
On 3/19/24 11:31, Antoine Tenart wrote: [snip] > @@ -163,6 +181,16 @@ static inline bool udp_unexpected_gso(struct sock *sk, struct sk_buff *skb) > !udp_test_bit(ACCEPT_FRAGLIST, sk)) > return true; > > + /* GSO packets lacking the SKB_GSO_UDP_TUNNEL/_CUSM bits might still s/CUSM/CSUM/ > + * land in a tunnel as the socket check in udp_gro_receive cannot be > + * foolproof. > + */ > + if (udp_encap_needed() && > + READ_ONCE(udp_sk(sk)->encap_rcv) && > + !(skb_shinfo(skb)->gso_type & > + (SKB_GSO_UDP_TUNNEL | SKB_GSO_UDP_TUNNEL_CSUM))) > + return true; > + > return false; > } > > diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c > index b9880743765c..e9719afe91cf 100644 > --- a/net/ipv4/udp_offload.c > +++ b/net/ipv4/udp_offload.c > @@ -551,8 +551,10 @@ struct sk_buff *udp_gro_receive(struct list_head *head, struct sk_buff *skb, > unsigned int off = skb_gro_offset(skb); > int flush = 1; > > - /* we can do L4 aggregation only if the packet can't land in a tunnel > - * otherwise we could corrupt the inner stream > + /* We can do L4 aggregation only if the packet can't land in a tunnel > + * otherwise we could corrupt the inner stream. Detecting such packets > + * cannot be foolproof and the aggregation might still happen in some > + * cases. Such packets should be caught in udp_unexpected_gso later. > */ > NAPI_GRO_CB(skb)->is_flist = 0; > if (!sk || !udp_sk(sk)->gro_receive) {
Quoting Jakub Kicinski (2024-03-20 03:41:24) > On Tue, 19 Mar 2024 10:31:36 +0100 Antoine Tenart wrote: > > +DECLARE_STATIC_KEY_FALSE(udp_encap_needed_key); > > nit: our build bot says you need to export this as well for v6=m. Thanks for the heads up, missed that. And udpv6_encap_needed_key needs to be defined outside ipv6.ko and exported as well. The following should fix the remaining build issues, diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 661d0e0d273f..c02bf011d4a6 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -582,6 +582,13 @@ static inline bool __udp_is_mcast_sock(struct net *net, const struct sock *sk, } DEFINE_STATIC_KEY_FALSE(udp_encap_needed_key); +EXPORT_SYMBOL(udp_encap_needed_key); + +#if IS_ENABLED(CONFIG_IPV6) +DEFINE_STATIC_KEY_FALSE(udpv6_encap_needed_key); +EXPORT_SYMBOL(udpv6_encap_needed_key); +#endif + void udp_encap_enable(void) { static_branch_inc(&udp_encap_needed_key); diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 7c1e6469d091..8b1dd7f51249 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -447,7 +447,7 @@ int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, goto try_again; } -DEFINE_STATIC_KEY_FALSE(udpv6_encap_needed_key); +DECLARE_STATIC_KEY_FALSE(udpv6_encap_needed_key); void udpv6_encap_enable(void) { static_branch_inc(&udpv6_encap_needed_key); Thanks! Antoine
Quoting Nikolay Aleksandrov (2024-03-20 11:34:01) > On 3/19/24 11:31, Antoine Tenart wrote: > [snip] > > @@ -163,6 +181,16 @@ static inline bool udp_unexpected_gso(struct sock *sk, struct sk_buff *skb) > > !udp_test_bit(ACCEPT_FRAGLIST, sk)) > > return true; > > > > + /* GSO packets lacking the SKB_GSO_UDP_TUNNEL/_CUSM bits might still > > s/CUSM/CSUM/ In the commit msg as well, thanks, will fix. Antoine
diff --git a/include/linux/udp.h b/include/linux/udp.h index 3748e82b627b..05231fff8703 100644 --- a/include/linux/udp.h +++ b/include/linux/udp.h @@ -150,6 +150,24 @@ static inline void udp_cmsg_recv(struct msghdr *msg, struct sock *sk, } } +DECLARE_STATIC_KEY_FALSE(udp_encap_needed_key); +#if IS_ENABLED(CONFIG_IPV6) +DECLARE_STATIC_KEY_FALSE(udpv6_encap_needed_key); +#endif + +static inline bool udp_encap_needed(void) +{ + if (static_branch_unlikely(&udp_encap_needed_key)) + return true; + +#if IS_ENABLED(CONFIG_IPV6) + if (static_branch_unlikely(&udpv6_encap_needed_key)) + return true; +#endif + + return false; +} + static inline bool udp_unexpected_gso(struct sock *sk, struct sk_buff *skb) { if (!skb_is_gso(skb)) @@ -163,6 +181,16 @@ static inline bool udp_unexpected_gso(struct sock *sk, struct sk_buff *skb) !udp_test_bit(ACCEPT_FRAGLIST, sk)) return true; + /* GSO packets lacking the SKB_GSO_UDP_TUNNEL/_CUSM bits might still + * land in a tunnel as the socket check in udp_gro_receive cannot be + * foolproof. + */ + if (udp_encap_needed() && + READ_ONCE(udp_sk(sk)->encap_rcv) && + !(skb_shinfo(skb)->gso_type & + (SKB_GSO_UDP_TUNNEL | SKB_GSO_UDP_TUNNEL_CSUM))) + return true; + return false; } diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c index b9880743765c..e9719afe91cf 100644 --- a/net/ipv4/udp_offload.c +++ b/net/ipv4/udp_offload.c @@ -551,8 +551,10 @@ struct sk_buff *udp_gro_receive(struct list_head *head, struct sk_buff *skb, unsigned int off = skb_gro_offset(skb); int flush = 1; - /* we can do L4 aggregation only if the packet can't land in a tunnel - * otherwise we could corrupt the inner stream + /* We can do L4 aggregation only if the packet can't land in a tunnel + * otherwise we could corrupt the inner stream. Detecting such packets + * cannot be foolproof and the aggregation might still happen in some + * cases. Such packets should be caught in udp_unexpected_gso later. */ NAPI_GRO_CB(skb)->is_flist = 0; if (!sk || !udp_sk(sk)->gro_receive) {