Linux 5.7.12
Greg Kroah-Hartman
maintainerI'm announcing the release of the 5.7.12 kernel.
All users of the 5.7 kernel series must upgrade.
The updated 5.7.y git tree can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git linux-5.7.y
and can be browsed at the normal kernel.org git web browser:
https://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git;a=summary
thanks,
greg k-h
------------
Makefile | 2 - drivers/base/regmap/regmap-debugfs.c | 6 ++++ drivers/net/wan/x25_asy.c | 21 ++++++++++----- fs/io_uring.c | 47 +++++++++++++++++++---------------- include/linux/tcp.h | 4 ++ net/ax25/af_ax25.c | 10 +++++-- net/core/dev.c | 2 - net/core/net-sysfs.c | 2 - net/core/rtnetlink.c | 3 +- net/core/sock_reuseport.c | 1 net/ipv4/tcp_input.c | 11 ++++---- net/ipv4/tcp_output.c | 13 +++++---- net/ipv4/udp.c | 17 +++++++----- net/ipv6/ip6_gre.c | 11 ++++---- net/ipv6/udp.c | 17 +++++++----- net/qrtr/qrtr.c | 1 net/rxrpc/recvmsg.c | 2 - net/rxrpc/sendmsg.c | 2 - net/sched/act_ct.c | 16 ++++++++++- net/sctp/stream.c | 27 +++++++++++++------- net/tipc/link.c | 2 - 21 files changed, 139 insertions(+), 78 deletions(-)
Cong Wang (1):
qrtr: orphan socket in qrtr_release()
Dan Carpenter (1):
AX.25: Prevent integer overflows in connect and sendmsg
David Howells (1):
rxrpc: Fix sendmsg() returning EPIPE due to recvmsg() returning ENODATA
Greg Kroah-Hartman (1):
Linux 5.7.12
Jens Axboe (1):
io_uring: ensure double poll additions work with both request types
Kuniyuki Iwashima (2):
udp: Copy has_conns in reuseport_grow().
udp: Improve load balancing for SO_REUSEPORT.
Miaohe Lin (1):
net: udp: Fix wrong clean up for IS_UDPLITE macro
Peilin Ye (2):
AX.25: Fix out-of-bounds read in ax25_connect() AX.25: Prevent out-of-bounds read in ax25_sendmsg()
Peng Fan (1):
regmap: debugfs: check count when read regmap file
Subash Abhinov Kasiviswanathan (1):
dev: Defer free of skbs in flush_backlog
Tung Nguyen (1):
tipc: allow to build NACK message in link timeout function
Wei Yongjun (1):
ip6_gre: fix null-ptr-deref in ip6gre_init_net()
Weilong Chen (1):
rtnetlink: Fix memory(net_device) leak when ->newlink fails
Xie He (1):
drivers/net/wan/x25_asy: Fix to make it work
Xin Long (2):
sctp: shrink stream outq only when new outcnt < old outcnt
sctp: shrink stream outq when fails to do addstream reconf
Xiongfeng Wang (1):
net-sysfs: add a newline when printing 'tx_timeout' by sysfs
Yuchung Cheng (1):
tcp: allow at most one TLP probe per flight
wenxu (1):
net/sched: act_ct: fix restore the qdisc_skb_cb after defrag
Greg Kroah-Hartman
maintainerMakefile +1 -1
@@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 5 PATCHLEVEL = 7 -SUBLEVEL = 11 +SUBLEVEL = 12 EXTRAVERSION = NAME = Kleptomaniac Octopus
drivers/base/regmap/regmap-debugfs.c +6 -0
@@ -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 ;
drivers/net/wan/x25_asy.c +14 -7
@@ -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 ;
fs/io_uring.c +26 -21
163 lines not on this page · raw message
include/linux/tcp.h +3 -1
@@ -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 */
net/ax25/af_ax25.c +8 -2
@@ -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; }
net/core/dev.c +1 -1
@@ -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); } }
net/core/net-sysfs.c +1 -1
@@ -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)
net/core/rtnetlink.c +2 -1
@@ -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; }
net/core/sock_reuseport.c +1 -0
@@ -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 *));
net/ipv4/tcp_input.c +6 -5
@@ -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)) {
net/ipv4/tcp_output.c +8 -5
@@ -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 ;
net/ipv4/udp.c +10 -7
@@ -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
net/ipv6/ip6_gre.c +6 -5
@@ -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; }
net/ipv6/udp.c +10 -7
@@ -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",
net/qrtr/qrtr.c +1 -0
@@ -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 ))
net/rxrpc/recvmsg.c +1 -1
@@ -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)) {
net/rxrpc/sendmsg.c +1 -1
@@ -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 ;
net/sched/act_ct.c +14 -2
@@ -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:
net/sctp/stream.c +18 -9
@@ -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 );
net/tipc/link.c +1 -1
@@ -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;