diff --git a/Makefile b/Makefile
index 12777a95833f..401d58b35e61 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 VERSION = 5
 PATCHLEVEL = 7
-SUBLEVEL = 11
+SUBLEVEL = 12
 EXTRAVERSION =
 NAME = Kleptomaniac Octopus
 
diff --git a/drivers/base/regmap/regmap-debugfs.c 
b/drivers/base/regmap/regmap-debugfs.c
index e16afa27700d..f58baff2be0a 100644
--- a/drivers/base/regmap/regmap-debugfs.c
+++ b/drivers/base/regmap/regmap-debugfs.c
@@ -227,6 +227,9 @@ static ssize_t regmap_read_debugfs(struct regmap *map, 
unsigned int from,
        if (*ppos < 0 || !count)
                return -EINVAL;
 
+       if (count > (PAGE_SIZE << (MAX_ORDER - 1)))
+               count = PAGE_SIZE << (MAX_ORDER - 1);
+
        buf = kmalloc(count, GFP_KERNEL);
        if (!buf)
                return -ENOMEM;
@@ -371,6 +374,9 @@ static ssize_t regmap_reg_ranges_read_file(struct file 
*file,
        if (*ppos < 0 || !count)
                return -EINVAL;
 
+       if (count > (PAGE_SIZE << (MAX_ORDER - 1)))
+               count = PAGE_SIZE << (MAX_ORDER - 1);
+
        buf = kmalloc(count, GFP_KERNEL);
        if (!buf)
                return -ENOMEM;
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
index 69773d228ec1..84640a0c13f3 100644
--- a/drivers/net/wan/x25_asy.c
+++ b/drivers/net/wan/x25_asy.c
@@ -183,7 +183,7 @@ static inline void x25_asy_unlock(struct x25_asy *sl)
        netif_wake_queue(sl->dev);
 }
 
-/* Send one completely decapsulated IP datagram to the IP layer. */
+/* Send an LAPB frame to the LAPB module to process. */
 
 static void x25_asy_bump(struct x25_asy *sl)
 {
@@ -195,13 +195,12 @@ static void x25_asy_bump(struct x25_asy *sl)
        count = sl->rcount;
        dev->stats.rx_bytes += count;
 
-       skb = dev_alloc_skb(count+1);
+       skb = dev_alloc_skb(count);
        if (skb == NULL) {
                netdev_warn(sl->dev, "memory squeeze, dropping packet\n");
                dev->stats.rx_dropped++;
                return;
        }
-       skb_push(skb, 1);       /* LAPB internal control */
        skb_put_data(skb, sl->rbuff, count);
        skb->protocol = x25_type_trans(skb, sl->dev);
        err = lapb_data_received(skb->dev, skb);
@@ -209,7 +208,6 @@ static void x25_asy_bump(struct x25_asy *sl)
                kfree_skb(skb);
                printk(KERN_DEBUG "x25_asy: data received err - %d\n", err);
        } else {
-               netif_rx(skb);
                dev->stats.rx_packets++;
        }
 }
@@ -356,12 +354,21 @@ static netdev_tx_t x25_asy_xmit(struct sk_buff *skb,
  */
 
 /*
- *     Called when I frame data arrives. We did the work above - throw it
- *     at the net layer.
+ *     Called when I frame data arrive. We add a pseudo header for upper
+ *     layers and pass it to upper layers.
  */
 
 static int x25_asy_data_indication(struct net_device *dev, struct sk_buff *skb)
 {
+       if (skb_cow(skb, 1)) {
+               kfree_skb(skb);
+               return NET_RX_DROP;
+       }
+       skb_push(skb, 1);
+       skb->data[0] = X25_IFACE_DATA;
+
+       skb->protocol = x25_type_trans(skb, dev);
+
        return netif_rx(skb);
 }
 
@@ -657,7 +664,7 @@ static void x25_asy_unesc(struct x25_asy *sl, unsigned char 
s)
        switch (s) {
        case X25_END:
                if (!test_and_clear_bit(SLF_ERROR, &sl->flags) &&
-                   sl->rcount > 2)
+                   sl->rcount >= 2)
                        x25_asy_bump(sl);
                clear_bit(SLF_ESCAPE, &sl->flags);
                sl->rcount = 0;
diff --git a/fs/io_uring.c b/fs/io_uring.c
index 51be3a20ade1..d0d3efaaa4d4 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -581,6 +581,7 @@ enum {
 
 struct async_poll {
        struct io_poll_iocb     poll;
+       struct io_poll_iocb     *double_poll;
        struct io_wq_work       work;
 };
 
@@ -4220,9 +4221,9 @@ static bool io_poll_rewait(struct io_kiocb *req, struct 
io_poll_iocb *poll)
        return false;
 }
 
-static void io_poll_remove_double(struct io_kiocb *req)
+static void io_poll_remove_double(struct io_kiocb *req, void *data)
 {
-       struct io_poll_iocb *poll = (struct io_poll_iocb *) req->io;
+       struct io_poll_iocb *poll = data;
 
        lockdep_assert_held(&req->ctx->completion_lock);
 
@@ -4242,7 +4243,7 @@ static void io_poll_complete(struct io_kiocb *req, 
__poll_t mask, int error)
 {
        struct io_ring_ctx *ctx = req->ctx;
 
-       io_poll_remove_double(req);
+       io_poll_remove_double(req, req->io);
        req->poll.done = true;
        io_cqring_fill_event(req, error ? error : mangle_poll(mask));
        io_commit_cqring(ctx);
@@ -4285,21 +4286,21 @@ static int io_poll_double_wake(struct wait_queue_entry 
*wait, unsigned mode,
                               int sync, void *key)
 {
        struct io_kiocb *req = wait->private;
-       struct io_poll_iocb *poll = (struct io_poll_iocb *) req->io;
+       struct io_poll_iocb *poll = req->apoll->double_poll;
        __poll_t mask = key_to_poll(key);
 
        /* for instances that support it check for an event match first: */
        if (mask && !(mask & poll->events))
                return 0;
 
-       if (req->poll.head) {
+       if (poll && poll->head) {
                bool done;
 
-               spin_lock(&req->poll.head->lock);
-               done = list_empty(&req->poll.wait.entry);
+               spin_lock(&poll->head->lock);
+               done = list_empty(&poll->wait.entry);
                if (!done)
-                       list_del_init(&req->poll.wait.entry);
-               spin_unlock(&req->poll.head->lock);
+                       list_del_init(&poll->wait.entry);
+               spin_unlock(&poll->head->lock);
                if (!done)
                        __io_async_wake(req, poll, mask, io_poll_task_func);
        }
@@ -4319,7 +4320,8 @@ static void io_init_poll_iocb(struct io_poll_iocb *poll, 
__poll_t events,
 }
 
 static void __io_queue_proc(struct io_poll_iocb *poll, struct io_poll_table 
*pt,
-                           struct wait_queue_head *head)
+                           struct wait_queue_head *head,
+                           struct io_poll_iocb **poll_ptr)
 {
        struct io_kiocb *req = pt->req;
 
@@ -4330,7 +4332,7 @@ static void __io_queue_proc(struct io_poll_iocb *poll, 
struct io_poll_table *pt,
         */
        if (unlikely(poll->head)) {
                /* already have a 2nd entry, fail a third attempt */
-               if (req->io) {
+               if (*poll_ptr) {
                        pt->error = -EINVAL;
                        return;
                }
@@ -4342,7 +4344,7 @@ static void __io_queue_proc(struct io_poll_iocb *poll, 
struct io_poll_table *pt,
                io_init_poll_iocb(poll, req->poll.events, io_poll_double_wake);
                refcount_inc(&req->refs);
                poll->wait.private = req;
-               req->io = (void *) poll;
+               *poll_ptr = poll;
        }
 
        pt->error = 0;
@@ -4354,8 +4356,9 @@ static void io_async_queue_proc(struct file *file, struct 
wait_queue_head *head,
                               struct poll_table_struct *p)
 {
        struct io_poll_table *pt = container_of(p, struct io_poll_table, pt);
+       struct async_poll *apoll = pt->req->apoll;
 
-       __io_queue_proc(&pt->req->apoll->poll, pt, head);
+       __io_queue_proc(&apoll->poll, pt, head, &apoll->double_poll);
 }
 
 static void io_sq_thread_drop_mm(struct io_ring_ctx *ctx)
@@ -4409,6 +4412,7 @@ static void io_async_task_func(struct callback_head *cb)
        memcpy(&req->work, &apoll->work, sizeof(req->work));
 
        if (canceled) {
+               kfree(apoll->double_poll);
                kfree(apoll);
                io_cqring_ev_posted(ctx);
 end_req:
@@ -4426,6 +4430,7 @@ static void io_async_task_func(struct callback_head *cb)
        __io_queue_sqe(req, NULL);
        mutex_unlock(&ctx->uring_lock);
 
+       kfree(apoll->double_poll);
        kfree(apoll);
 }
 
@@ -4497,7 +4502,6 @@ static bool io_arm_poll_handler(struct io_kiocb *req)
        struct async_poll *apoll;
        struct io_poll_table ipt;
        __poll_t mask, ret;
-       bool had_io;
 
        if (!req->file || !file_can_poll(req->file))
                return false;
@@ -4509,10 +4513,10 @@ static bool io_arm_poll_handler(struct io_kiocb *req)
        apoll = kmalloc(sizeof(*apoll), GFP_ATOMIC);
        if (unlikely(!apoll))
                return false;
+       apoll->double_poll = NULL;
 
        req->flags |= REQ_F_POLLED;
        memcpy(&apoll->work, &req->work, sizeof(req->work));
-       had_io = req->io != NULL;
 
        get_task_struct(current);
        req->task = current;
@@ -4531,12 +4535,10 @@ static bool io_arm_poll_handler(struct io_kiocb *req)
        ret = __io_arm_poll_handler(req, &apoll->poll, &ipt, mask,
                                        io_async_wake);
        if (ret) {
-               ipt.error = 0;
-               /* only remove double add if we did it here */
-               if (!had_io)
-                       io_poll_remove_double(req);
+               io_poll_remove_double(req, apoll->double_poll);
                spin_unlock_irq(&ctx->completion_lock);
                memcpy(&req->work, &apoll->work, sizeof(req->work));
+               kfree(apoll->double_poll);
                kfree(apoll);
                return false;
        }
@@ -4567,11 +4569,13 @@ static bool io_poll_remove_one(struct io_kiocb *req)
        bool do_complete;
 
        if (req->opcode == IORING_OP_POLL_ADD) {
-               io_poll_remove_double(req);
+               io_poll_remove_double(req, req->io);
                do_complete = __io_poll_remove_one(req, &req->poll);
        } else {
                struct async_poll *apoll = req->apoll;
 
+               io_poll_remove_double(req, apoll->double_poll);
+
                /* non-poll requests have submit ref still */
                do_complete = __io_poll_remove_one(req, &apoll->poll);
                if (do_complete) {
@@ -4582,6 +4586,7 @@ static bool io_poll_remove_one(struct io_kiocb *req)
                         * final reference.
                         */
                        memcpy(&req->work, &apoll->work, sizeof(req->work));
+                       kfree(apoll->double_poll);
                        kfree(apoll);
                }
        }
@@ -4682,7 +4687,7 @@ static void io_poll_queue_proc(struct file *file, struct 
wait_queue_head *head,
 {
        struct io_poll_table *pt = container_of(p, struct io_poll_table, pt);
 
-       __io_queue_proc(&pt->req->poll, pt, head);
+       __io_queue_proc(&pt->req->poll, pt, head, (struct io_poll_iocb **) 
&pt->req->io);
 }
 
 static int io_poll_add_prep(struct io_kiocb *req, const struct io_uring_sqe 
*sqe)
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 4f8159e90ce1..0bba582e83ca 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -217,6 +217,8 @@ struct tcp_sock {
        } rack;
        u16     advmss;         /* Advertised MSS                       */
        u8      compressed_ack;
+       u8      tlp_retrans:1,  /* TLP is a retransmission */
+               unused:7;
        u32     chrono_start;   /* Start time in jiffies of a TCP chrono */
        u32     chrono_stat[3]; /* Time in jiffies for chrono_stat stats */
        u8      chrono_type:2,  /* current chronograph type */
@@ -239,7 +241,7 @@ struct tcp_sock {
                save_syn:1,     /* Save headers of SYN packet */
                is_cwnd_limited:1,/* forward progress limited by snd_cwnd? */
                syn_smc:1;      /* SYN includes SMC */
-       u32     tlp_high_seq;   /* snd_nxt at the time of TLP retransmit. */
+       u32     tlp_high_seq;   /* snd_nxt at the time of TLP */
 
        u32     tcp_tx_delay;   /* delay (in usec) added to TX packets */
        u64     tcp_wstamp_ns;  /* departure time for next sent data packet */
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index fd91cd34f25e..dec3f35467c9 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -1187,7 +1187,10 @@ static int __must_check ax25_connect(struct socket *sock,
        if (addr_len > sizeof(struct sockaddr_ax25) &&
            fsa->fsa_ax25.sax25_ndigis != 0) {
                /* Valid number of digipeaters ? */
-               if (fsa->fsa_ax25.sax25_ndigis < 1 || 
fsa->fsa_ax25.sax25_ndigis > AX25_MAX_DIGIS) {
+               if (fsa->fsa_ax25.sax25_ndigis < 1 ||
+                   fsa->fsa_ax25.sax25_ndigis > AX25_MAX_DIGIS ||
+                   addr_len < sizeof(struct sockaddr_ax25) +
+                   sizeof(ax25_address) * fsa->fsa_ax25.sax25_ndigis) {
                        err = -EINVAL;
                        goto out_release;
                }
@@ -1507,7 +1510,10 @@ static int ax25_sendmsg(struct socket *sock, struct 
msghdr *msg, size_t len)
                        struct full_sockaddr_ax25 *fsa = (struct 
full_sockaddr_ax25 *)usax;
 
                        /* Valid number of digipeaters ? */
-                       if (usax->sax25_ndigis < 1 || usax->sax25_ndigis > 
AX25_MAX_DIGIS) {
+                       if (usax->sax25_ndigis < 1 ||
+                           usax->sax25_ndigis > AX25_MAX_DIGIS ||
+                           addr_len < sizeof(struct sockaddr_ax25) +
+                           sizeof(ax25_address) * usax->sax25_ndigis) {
                                err = -EINVAL;
                                goto out;
                        }
diff --git a/net/core/dev.c b/net/core/dev.c
index c9ee5d80d5ea..c1c2688a955c 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -5504,7 +5504,7 @@ static void flush_backlog(struct work_struct *work)
        skb_queue_walk_safe(&sd->input_pkt_queue, skb, tmp) {
                if (skb->dev->reg_state == NETREG_UNREGISTERING) {
                        __skb_unlink(skb, &sd->input_pkt_queue);
-                       kfree_skb(skb);
+                       dev_kfree_skb_irq(skb);
                        input_queue_head_incr(sd);
                }
        }
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 4773ad6ec111..f67f5ca39d63 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -1077,7 +1077,7 @@ static ssize_t tx_timeout_show(struct netdev_queue 
*queue, char *buf)
        trans_timeout = queue->trans_timeout;
        spin_unlock_irq(&queue->_xmit_lock);
 
-       return sprintf(buf, "%lu", trans_timeout);
+       return sprintf(buf, fmt_ulong, trans_timeout);
 }
 
 static unsigned int get_netdev_queue_index(struct netdev_queue *queue)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 709ebbf8ab5b..78345e39e54a 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -3337,7 +3337,8 @@ static int __rtnl_newlink(struct sk_buff *skb, struct 
nlmsghdr *nlh,
                 */
                if (err < 0) {
                        /* If device is not registered at all, free it now */
-                       if (dev->reg_state == NETREG_UNINITIALIZED)
+                       if (dev->reg_state == NETREG_UNINITIALIZED ||
+                           dev->reg_state == NETREG_UNREGISTERED)
                                free_netdev(dev);
                        goto out;
                }
diff --git a/net/core/sock_reuseport.c b/net/core/sock_reuseport.c
index adcb3aea576d..bbdd3c7b6cb5 100644
--- a/net/core/sock_reuseport.c
+++ b/net/core/sock_reuseport.c
@@ -101,6 +101,7 @@ static struct sock_reuseport *reuseport_grow(struct 
sock_reuseport *reuse)
        more_reuse->prog = reuse->prog;
        more_reuse->reuseport_id = reuse->reuseport_id;
        more_reuse->bind_inany = reuse->bind_inany;
+       more_reuse->has_conns = reuse->has_conns;
 
        memcpy(more_reuse->socks, reuse->socks,
               reuse->num_socks * sizeof(struct sock *));
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 31c58e00d25b..32ac66a8c657 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -3506,10 +3506,8 @@ static void tcp_replace_ts_recent(struct tcp_sock *tp, 
u32 seq)
        }
 }
 
-/* This routine deals with acks during a TLP episode.
- * We mark the end of a TLP episode on receiving TLP dupack or when
- * ack is after tlp_high_seq.
- * Ref: loss detection algorithm in draft-dukkipati-tcpm-tcp-loss-probe.
+/* This routine deals with acks during a TLP episode and ends an episode by
+ * resetting tlp_high_seq. Ref: TLP algorithm in draft-ietf-tcpm-rack
  */
 static void tcp_process_tlp_ack(struct sock *sk, u32 ack, int flag)
 {
@@ -3518,7 +3516,10 @@ static void tcp_process_tlp_ack(struct sock *sk, u32 
ack, int flag)
        if (before(ack, tp->tlp_high_seq))
                return;
 
-       if (flag & FLAG_DSACKING_ACK) {
+       if (!tp->tlp_retrans) {
+               /* TLP of new data has been acknowledged */
+               tp->tlp_high_seq = 0;
+       } else if (flag & FLAG_DSACKING_ACK) {
                /* This DSACK means original and TLP probe arrived; no loss */
                tp->tlp_high_seq = 0;
        } else if (after(ack, tp->tlp_high_seq)) {
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index bee2f9b8b8a1..b1c2484b4314 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -2625,6 +2625,11 @@ void tcp_send_loss_probe(struct sock *sk)
        int pcount;
        int mss = tcp_current_mss(sk);
 
+       /* At most one outstanding TLP */
+       if (tp->tlp_high_seq)
+               goto rearm_timer;
+
+       tp->tlp_retrans = 0;
        skb = tcp_send_head(sk);
        if (skb && tcp_snd_wnd_test(tp, skb, mss)) {
                pcount = tp->packets_out;
@@ -2642,10 +2647,6 @@ void tcp_send_loss_probe(struct sock *sk)
                return;
        }
 
-       /* At most one outstanding TLP retransmission. */
-       if (tp->tlp_high_seq)
-               goto rearm_timer;
-
        if (skb_still_in_host_queue(sk, skb))
                goto rearm_timer;
 
@@ -2667,10 +2668,12 @@ void tcp_send_loss_probe(struct sock *sk)
        if (__tcp_retransmit_skb(sk, skb, 1))
                goto rearm_timer;
 
+       tp->tlp_retrans = 1;
+
+probe_sent:
        /* Record snd_nxt for loss detection. */
        tp->tlp_high_seq = tp->snd_nxt;
 
-probe_sent:
        NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPLOSSPROBES);
        /* Reset s.t. tcp_rearm_rto will restart timer from now */
        inet_csk(sk)->icsk_pending = 0;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 32564b350823..6ffef9861fa9 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -413,7 +413,7 @@ static struct sock *udp4_lib_lookup2(struct net *net,
                                     struct udp_hslot *hslot2,
                                     struct sk_buff *skb)
 {
-       struct sock *sk, *result;
+       struct sock *sk, *result, *reuseport_result;
        int score, badness;
        u32 hash = 0;
 
@@ -423,17 +423,20 @@ static struct sock *udp4_lib_lookup2(struct net *net,
                score = compute_score(sk, net, saddr, sport,
                                      daddr, hnum, dif, sdif);
                if (score > badness) {
+                       reuseport_result = NULL;
+
                        if (sk->sk_reuseport &&
                            sk->sk_state != TCP_ESTABLISHED) {
                                hash = udp_ehashfn(net, daddr, hnum,
                                                   saddr, sport);
-                               result = reuseport_select_sock(sk, hash, skb,
-                                                       sizeof(struct udphdr));
-                               if (result && !reuseport_has_conns(sk, false))
-                                       return result;
+                               reuseport_result = reuseport_select_sock(sk, 
hash, skb,
+                                                                        
sizeof(struct udphdr));
+                               if (reuseport_result && 
!reuseport_has_conns(sk, false))
+                                       return reuseport_result;
                        }
+
+                       result = reuseport_result ? : sk;
                        badness = score;
-                       result = sk;
                }
        }
        return result;
@@ -2048,7 +2051,7 @@ static int udp_queue_rcv_one_skb(struct sock *sk, struct 
sk_buff *skb)
        /*
         *      UDP-Lite specific tests, ignored on UDP sockets
         */
-       if ((is_udplite & UDPLITE_RECV_CC)  &&  UDP_SKB_CB(skb)->partial_cov) {
+       if ((up->pcflag & UDPLITE_RECV_CC)  &&  UDP_SKB_CB(skb)->partial_cov) {
 
                /*
                 * MIB statistics other than incrementing the error count are
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 6532bde82b40..3a57fb9ce049 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -1562,17 +1562,18 @@ static void ip6gre_destroy_tunnels(struct net *net, 
struct list_head *head)
 static int __net_init ip6gre_init_net(struct net *net)
 {
        struct ip6gre_net *ign = net_generic(net, ip6gre_net_id);
+       struct net_device *ndev;
        int err;
 
        if (!net_has_fallback_tunnels(net))
                return 0;
-       ign->fb_tunnel_dev = alloc_netdev(sizeof(struct ip6_tnl), "ip6gre0",
-                                         NET_NAME_UNKNOWN,
-                                         ip6gre_tunnel_setup);
-       if (!ign->fb_tunnel_dev) {
+       ndev = alloc_netdev(sizeof(struct ip6_tnl), "ip6gre0",
+                           NET_NAME_UNKNOWN, ip6gre_tunnel_setup);
+       if (!ndev) {
                err = -ENOMEM;
                goto err_alloc_dev;
        }
+       ign->fb_tunnel_dev = ndev;
        dev_net_set(ign->fb_tunnel_dev, net);
        /* FB netdevice is special: we have one, and only one per netns.
         * Allowing to move it to another netns is clearly unsafe.
@@ -1592,7 +1593,7 @@ static int __net_init ip6gre_init_net(struct net *net)
        return 0;
 
 err_reg_dev:
-       free_netdev(ign->fb_tunnel_dev);
+       free_netdev(ndev);
 err_alloc_dev:
        return err;
 }
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 7d4151747340..a8d74f44056a 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -148,7 +148,7 @@ static struct sock *udp6_lib_lookup2(struct net *net,
                int dif, int sdif, struct udp_hslot *hslot2,
                struct sk_buff *skb)
 {
-       struct sock *sk, *result;
+       struct sock *sk, *result, *reuseport_result;
        int score, badness;
        u32 hash = 0;
 
@@ -158,17 +158,20 @@ static struct sock *udp6_lib_lookup2(struct net *net,
                score = compute_score(sk, net, saddr, sport,
                                      daddr, hnum, dif, sdif);
                if (score > badness) {
+                       reuseport_result = NULL;
+
                        if (sk->sk_reuseport &&
                            sk->sk_state != TCP_ESTABLISHED) {
                                hash = udp6_ehashfn(net, daddr, hnum,
                                                    saddr, sport);
 
-                               result = reuseport_select_sock(sk, hash, skb,
-                                                       sizeof(struct udphdr));
-                               if (result && !reuseport_has_conns(sk, false))
-                                       return result;
+                               reuseport_result = reuseport_select_sock(sk, 
hash, skb,
+                                                                        
sizeof(struct udphdr));
+                               if (reuseport_result && 
!reuseport_has_conns(sk, false))
+                                       return reuseport_result;
                        }
-                       result = sk;
+
+                       result = reuseport_result ? : sk;
                        badness = score;
                }
        }
@@ -643,7 +646,7 @@ static int udpv6_queue_rcv_one_skb(struct sock *sk, struct 
sk_buff *skb)
        /*
         * UDP-Lite specific tests, ignored on UDP sockets (see net/ipv4/udp.c).
         */
-       if ((is_udplite & UDPLITE_RECV_CC)  &&  UDP_SKB_CB(skb)->partial_cov) {
+       if ((up->pcflag & UDPLITE_RECV_CC)  &&  UDP_SKB_CB(skb)->partial_cov) {
 
                if (up->pcrlen == 0) {          /* full coverage was set  */
                        net_dbg_ratelimited("UDPLITE6: partial coverage %d 
while full coverage %d requested\n",
diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c
index 24a8c3c6da0d..300a104b9a0f 100644
--- a/net/qrtr/qrtr.c
+++ b/net/qrtr/qrtr.c
@@ -1180,6 +1180,7 @@ static int qrtr_release(struct socket *sock)
                sk->sk_state_change(sk);
 
        sock_set_flag(sk, SOCK_DEAD);
+       sock_orphan(sk);
        sock->sk = NULL;
 
        if (!sock_flag(sk, SOCK_ZAPPED))
diff --git a/net/rxrpc/recvmsg.c b/net/rxrpc/recvmsg.c
index 8578c39ec839..6896a33ef842 100644
--- a/net/rxrpc/recvmsg.c
+++ b/net/rxrpc/recvmsg.c
@@ -464,7 +464,7 @@ int rxrpc_recvmsg(struct socket *sock, struct msghdr *msg, 
size_t len,
            list_empty(&rx->recvmsg_q) &&
            rx->sk.sk_state != RXRPC_SERVER_LISTENING) {
                release_sock(&rx->sk);
-               return -ENODATA;
+               return -EAGAIN;
        }
 
        if (list_empty(&rx->recvmsg_q)) {
diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c
index 5e9c43d4a314..49d03c8c64da 100644
--- a/net/rxrpc/sendmsg.c
+++ b/net/rxrpc/sendmsg.c
@@ -306,7 +306,7 @@ static int rxrpc_send_data(struct rxrpc_sock *rx,
        /* this should be in poll */
        sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk);
 
-       if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))
+       if (sk->sk_shutdown & SEND_SHUTDOWN)
                return -EPIPE;
 
        more = msg->msg_flags & MSG_MORE;
diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c
index 6a114f80e54b..e191f2728389 100644
--- a/net/sched/act_ct.c
+++ b/net/sched/act_ct.c
@@ -671,9 +671,10 @@ static int tcf_ct_ipv6_is_fragment(struct sk_buff *skb, 
bool *frag)
 }
 
 static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb,
-                                  u8 family, u16 zone)
+                                  u8 family, u16 zone, bool *defrag)
 {
        enum ip_conntrack_info ctinfo;
+       struct qdisc_skb_cb cb;
        struct nf_conn *ct;
        int err = 0;
        bool frag;
@@ -691,6 +692,7 @@ static int tcf_ct_handle_fragments(struct net *net, struct 
sk_buff *skb,
                return err;
 
        skb_get(skb);
+       cb = *qdisc_skb_cb(skb);
 
        if (family == NFPROTO_IPV4) {
                enum ip_defrag_users user = IP_DEFRAG_CONNTRACK_IN + zone;
@@ -701,6 +703,9 @@ static int tcf_ct_handle_fragments(struct net *net, struct 
sk_buff *skb,
                local_bh_enable();
                if (err && err != -EINPROGRESS)
                        goto out_free;
+
+               if (!err)
+                       *defrag = true;
        } else { /* NFPROTO_IPV6 */
 #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
                enum ip6_defrag_users user = IP6_DEFRAG_CONNTRACK_IN + zone;
@@ -709,12 +714,16 @@ static int tcf_ct_handle_fragments(struct net *net, 
struct sk_buff *skb,
                err = nf_ct_frag6_gather(net, skb, user);
                if (err && err != -EINPROGRESS)
                        goto out_free;
+
+               if (!err)
+                       *defrag = true;
 #else
                err = -EOPNOTSUPP;
                goto out_free;
 #endif
        }
 
+       *qdisc_skb_cb(skb) = cb;
        skb_clear_hash(skb);
        skb->ignore_df = 1;
        return err;
@@ -912,6 +921,7 @@ static int tcf_ct_act(struct sk_buff *skb, const struct 
tc_action *a,
        int nh_ofs, err, retval;
        struct tcf_ct_params *p;
        bool skip_add = false;
+       bool defrag = false;
        struct nf_conn *ct;
        u8 family;
 
@@ -942,7 +952,7 @@ static int tcf_ct_act(struct sk_buff *skb, const struct 
tc_action *a,
         */
        nh_ofs = skb_network_offset(skb);
        skb_pull_rcsum(skb, nh_ofs);
-       err = tcf_ct_handle_fragments(net, skb, family, p->zone);
+       err = tcf_ct_handle_fragments(net, skb, family, p->zone, &defrag);
        if (err == -EINPROGRESS) {
                retval = TC_ACT_STOLEN;
                goto out;
@@ -1010,6 +1020,8 @@ static int tcf_ct_act(struct sk_buff *skb, const struct 
tc_action *a,
 
 out:
        tcf_action_update_bstats(&c->common, skb);
+       if (defrag)
+               qdisc_skb_cb(skb)->pkt_len = skb->len;
        return retval;
 
 drop:
diff --git a/net/sctp/stream.c b/net/sctp/stream.c
index 67f7e71f9129..bda2536dd740 100644
--- a/net/sctp/stream.c
+++ b/net/sctp/stream.c
@@ -22,17 +22,11 @@
 #include <net/sctp/sm.h>
 #include <net/sctp/stream_sched.h>
 
-/* Migrates chunks from stream queues to new stream queues if needed,
- * but not across associations. Also, removes those chunks to streams
- * higher than the new max.
- */
-static void sctp_stream_outq_migrate(struct sctp_stream *stream,
-                                    struct sctp_stream *new, __u16 outcnt)
+static void sctp_stream_shrink_out(struct sctp_stream *stream, __u16 outcnt)
 {
        struct sctp_association *asoc;
        struct sctp_chunk *ch, *temp;
        struct sctp_outq *outq;
-       int i;
 
        asoc = container_of(stream, struct sctp_association, stream);
        outq = &asoc->outqueue;
@@ -56,6 +50,19 @@ static void sctp_stream_outq_migrate(struct sctp_stream 
*stream,
 
                sctp_chunk_free(ch);
        }
+}
+
+/* Migrates chunks from stream queues to new stream queues if needed,
+ * but not across associations. Also, removes those chunks to streams
+ * higher than the new max.
+ */
+static void sctp_stream_outq_migrate(struct sctp_stream *stream,
+                                    struct sctp_stream *new, __u16 outcnt)
+{
+       int i;
+
+       if (stream->outcnt > outcnt)
+               sctp_stream_shrink_out(stream, outcnt);
 
        if (new) {
                /* Here we actually move the old ext stuff into the new
@@ -1037,11 +1044,13 @@ struct sctp_chunk *sctp_process_strreset_resp(
                nums = ntohs(addstrm->number_of_streams);
                number = stream->outcnt - nums;
 
-               if (result == SCTP_STRRESET_PERFORMED)
+               if (result == SCTP_STRRESET_PERFORMED) {
                        for (i = number; i < stream->outcnt; i++)
                                SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;
-               else
+               } else {
+                       sctp_stream_shrink_out(stream, number);
                        stream->outcnt = number;
+               }
 
                *evp = sctp_ulpevent_make_stream_change_event(asoc, flags,
                        0, nums, GFP_ATOMIC);
diff --git a/net/tipc/link.c b/net/tipc/link.c
index d4675e922a8f..e18369201a15 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -813,11 +813,11 @@ int tipc_link_timeout(struct tipc_link *l, struct 
sk_buff_head *xmitq)
                state |= l->bc_rcvlink->rcv_unacked;
                state |= l->rcv_unacked;
                state |= !skb_queue_empty(&l->transmq);
-               state |= !skb_queue_empty(&l->deferdq);
                probe = mstate->probing;
                probe |= l->silent_intv_cnt;
                if (probe || mstate->monitoring)
                        l->silent_intv_cnt++;
+               probe |= !skb_queue_empty(&l->deferdq);
                if (l->snd_nxt == l->checkpoint) {
                        tipc_link_update_cwin(l, 0, 0);
                        probe = true;
  • Linux 5.7.12 Greg Kroah-Hartman
    • Re: Linux 5.7.12 Greg Kroah-Hartman

Reply via email to