net: gro: add flush check in udp_gro_receive_segment
authorRichard Gobert <richardbgobert@gmail.com>
Tue, 30 Apr 2024 14:35:55 +0000 (16:35 +0200)
committerPaolo Abeni <pabeni@redhat.com>
Thu, 2 May 2024 09:03:20 +0000 (11:03 +0200)
GRO-GSO path is supposed to be transparent and as such L3 flush checks are
relevant to all UDP flows merging in GRO. This patch uses the same logic
and code from tcp_gro_receive, terminating merge if flush is non zero.

Fixes: e20cf8d3f1f7 ("udp: implement GRO for plain UDP sockets.")
Signed-off-by: Richard Gobert <richardbgobert@gmail.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
net/ipv4/udp_offload.c

index fd29d21d579c185eb5cb54e05ffd00e703966ed3..8721fe5beca2bea692eb2cfa454e724e649cea6d 100644 (file)
@@ -471,6 +471,7 @@ static struct sk_buff *udp_gro_receive_segment(struct list_head *head,
        struct sk_buff *p;
        unsigned int ulen;
        int ret = 0;
+       int flush;
 
        /* requires non zero csum, for symmetry with GSO */
        if (!uh->check) {
@@ -504,13 +505,22 @@ static struct sk_buff *udp_gro_receive_segment(struct list_head *head,
                        return p;
                }
 
+               flush = NAPI_GRO_CB(p)->flush;
+
+               if (NAPI_GRO_CB(p)->flush_id != 1 ||
+                   NAPI_GRO_CB(p)->count != 1 ||
+                   !NAPI_GRO_CB(p)->is_atomic)
+                       flush |= NAPI_GRO_CB(p)->flush_id;
+               else
+                       NAPI_GRO_CB(p)->is_atomic = false;
+
                /* Terminate the flow on len mismatch or if it grow "too much".
                 * Under small packet flood GRO count could elsewhere grow a lot
                 * leading to excessive truesize values.
                 * On len mismatch merge the first packet shorter than gso_size,
                 * otherwise complete the GRO packet.
                 */
-               if (ulen > ntohs(uh2->len)) {
+               if (ulen > ntohs(uh2->len) || flush) {
                        pp = p;
                } else {
                        if (NAPI_GRO_CB(skb)->is_flist) {