This is the 4.19.136 stable release
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAl8kSR4ACgkQONu9yGCS aT4GxA/9GRHQlFrC3+zbFEm8lB1q/H1Ghv8CVzxokDyPlvQ9jbzMl0gNBhyjnb3D DAJiTXZUP4A2cq/sM98+ainjLTq7mJNXRIgbJ1pIutY25o7M8YPTLzn+A8Yvj521 K105aEVggMGeICqT3lL8pf9Ttom+7nyOPtoqPoWwjvW2oKQP/Gbzj97m/61xMCWk pveOxgv4cqOdJfxg/9JhzVpzPHxmLTmSf5XW/ygKJa3aEOnFJhI3lZQtENcCoIlD F0pv9rw2f4P8XLAtgBV6uhT/+871POYV+uTEYlAiF3O2JvVHq9KJY6kWycdRsOMD cvZaQ+9eqA4vhg1KpLSqxazY6+AmvhJ7wuTrPfuvnvGafB3FZr57J9qVk1LH5P0Y b4kMaKC4A67YzJHJ4Lz/Y2aKI3XgkFRPjIhty9ora/FnTzCii0MCRJq6rM6ZcYAh uaj4MZOOiB77OkwDdxLjEWdeIv73vcZP70Uzbp55OCOyF9g27MNt645uX9vXRwNR L0OxhWZyljziI34xnU9fekl1wTC4TBr82/s+XDl6BoicKUmXgz8xnrEw/yCdvmx0 +Oeagt98NagCoRlBYpatgFn+z2OSL5W85XgrXKobUJUa7KIpSthBYqA4rIRxoa+Y A5/n2tuv6jNm1ywD5S6aCxACU8hpweqOoL8soshmFdqxwL1jl/0= =aFv6 -----END PGP SIGNATURE----- Merge 4.19.136 into android-4.19-stable Changes in 4.19.136 AX.25: Fix out-of-bounds read in ax25_connect() AX.25: Prevent out-of-bounds read in ax25_sendmsg() dev: Defer free of skbs in flush_backlog drivers/net/wan/x25_asy: Fix to make it work ip6_gre: fix null-ptr-deref in ip6gre_init_net() net-sysfs: add a newline when printing 'tx_timeout' by sysfs net: udp: Fix wrong clean up for IS_UDPLITE macro qrtr: orphan socket in qrtr_release() rxrpc: Fix sendmsg() returning EPIPE due to recvmsg() returning ENODATA tcp: allow at most one TLP probe per flight AX.25: Prevent integer overflows in connect and sendmsg sctp: shrink stream outq only when new outcnt < old outcnt sctp: shrink stream outq when fails to do addstream reconf udp: Copy has_conns in reuseport_grow(). udp: Improve load balancing for SO_REUSEPORT. rtnetlink: Fix memory(net_device) leak when ->newlink fails regmap: debugfs: check count when read regmap file Linux 4.19.136 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I642a68276dffc3521d8809024f457c1049012348
This commit is contained in:
commit
204dd19a9b
2
Makefile
2
Makefile
@ -1,7 +1,7 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
VERSION = 4
|
VERSION = 4
|
||||||
PATCHLEVEL = 19
|
PATCHLEVEL = 19
|
||||||
SUBLEVEL = 135
|
SUBLEVEL = 136
|
||||||
EXTRAVERSION =
|
EXTRAVERSION =
|
||||||
NAME = "People's Front"
|
NAME = "People's Front"
|
||||||
|
|
||||||
|
@ -209,6 +209,9 @@ static ssize_t regmap_read_debugfs(struct regmap *map, unsigned int from,
|
|||||||
if (*ppos < 0 || !count)
|
if (*ppos < 0 || !count)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (count > (PAGE_SIZE << (MAX_ORDER - 1)))
|
||||||
|
count = PAGE_SIZE << (MAX_ORDER - 1);
|
||||||
|
|
||||||
buf = kmalloc(count, GFP_KERNEL);
|
buf = kmalloc(count, GFP_KERNEL);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -357,6 +360,9 @@ static ssize_t regmap_reg_ranges_read_file(struct file *file,
|
|||||||
if (*ppos < 0 || !count)
|
if (*ppos < 0 || !count)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (count > (PAGE_SIZE << (MAX_ORDER - 1)))
|
||||||
|
count = PAGE_SIZE << (MAX_ORDER - 1);
|
||||||
|
|
||||||
buf = kmalloc(count, GFP_KERNEL);
|
buf = kmalloc(count, GFP_KERNEL);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -183,7 +183,7 @@ static inline void x25_asy_unlock(struct x25_asy *sl)
|
|||||||
netif_wake_queue(sl->dev);
|
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)
|
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;
|
count = sl->rcount;
|
||||||
dev->stats.rx_bytes += count;
|
dev->stats.rx_bytes += count;
|
||||||
|
|
||||||
skb = dev_alloc_skb(count+1);
|
skb = dev_alloc_skb(count);
|
||||||
if (skb == NULL) {
|
if (skb == NULL) {
|
||||||
netdev_warn(sl->dev, "memory squeeze, dropping packet\n");
|
netdev_warn(sl->dev, "memory squeeze, dropping packet\n");
|
||||||
dev->stats.rx_dropped++;
|
dev->stats.rx_dropped++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
skb_push(skb, 1); /* LAPB internal control */
|
|
||||||
skb_put_data(skb, sl->rbuff, count);
|
skb_put_data(skb, sl->rbuff, count);
|
||||||
skb->protocol = x25_type_trans(skb, sl->dev);
|
skb->protocol = x25_type_trans(skb, sl->dev);
|
||||||
err = lapb_data_received(skb->dev, skb);
|
err = lapb_data_received(skb->dev, skb);
|
||||||
@ -209,7 +208,6 @@ static void x25_asy_bump(struct x25_asy *sl)
|
|||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
printk(KERN_DEBUG "x25_asy: data received err - %d\n", err);
|
printk(KERN_DEBUG "x25_asy: data received err - %d\n", err);
|
||||||
} else {
|
} else {
|
||||||
netif_rx(skb);
|
|
||||||
dev->stats.rx_packets++;
|
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
|
* Called when I frame data arrive. We add a pseudo header for upper
|
||||||
* at the net layer.
|
* layers and pass it to upper layers.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int x25_asy_data_indication(struct net_device *dev, struct sk_buff *skb)
|
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);
|
return netif_rx(skb);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -657,7 +664,7 @@ static void x25_asy_unesc(struct x25_asy *sl, unsigned char s)
|
|||||||
switch (s) {
|
switch (s) {
|
||||||
case X25_END:
|
case X25_END:
|
||||||
if (!test_and_clear_bit(SLF_ERROR, &sl->flags) &&
|
if (!test_and_clear_bit(SLF_ERROR, &sl->flags) &&
|
||||||
sl->rcount > 2)
|
sl->rcount >= 2)
|
||||||
x25_asy_bump(sl);
|
x25_asy_bump(sl);
|
||||||
clear_bit(SLF_ESCAPE, &sl->flags);
|
clear_bit(SLF_ESCAPE, &sl->flags);
|
||||||
sl->rcount = 0;
|
sl->rcount = 0;
|
||||||
|
@ -225,6 +225,8 @@ struct tcp_sock {
|
|||||||
} rack;
|
} rack;
|
||||||
u16 advmss; /* Advertised MSS */
|
u16 advmss; /* Advertised MSS */
|
||||||
u8 compressed_ack;
|
u8 compressed_ack;
|
||||||
|
u8 tlp_retrans:1, /* TLP is a retransmission */
|
||||||
|
unused_1:7;
|
||||||
u32 chrono_start; /* Start time in jiffies of a TCP chrono */
|
u32 chrono_start; /* Start time in jiffies of a TCP chrono */
|
||||||
u32 chrono_stat[3]; /* Time in jiffies for chrono_stat stats */
|
u32 chrono_stat[3]; /* Time in jiffies for chrono_stat stats */
|
||||||
u8 chrono_type:2, /* current chronograph type */
|
u8 chrono_type:2, /* current chronograph type */
|
||||||
@ -247,7 +249,7 @@ struct tcp_sock {
|
|||||||
save_syn:1, /* Save headers of SYN packet */
|
save_syn:1, /* Save headers of SYN packet */
|
||||||
is_cwnd_limited:1,/* forward progress limited by snd_cwnd? */
|
is_cwnd_limited:1,/* forward progress limited by snd_cwnd? */
|
||||||
syn_smc:1; /* SYN includes SMC */
|
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 */
|
||||||
|
|
||||||
/* RTT measurement */
|
/* RTT measurement */
|
||||||
u64 tcp_mstamp; /* most recent packet received/sent */
|
u64 tcp_mstamp; /* most recent packet received/sent */
|
||||||
|
@ -1190,7 +1190,10 @@ static int __must_check ax25_connect(struct socket *sock,
|
|||||||
if (addr_len > sizeof(struct sockaddr_ax25) &&
|
if (addr_len > sizeof(struct sockaddr_ax25) &&
|
||||||
fsa->fsa_ax25.sax25_ndigis != 0) {
|
fsa->fsa_ax25.sax25_ndigis != 0) {
|
||||||
/* Valid number of digipeaters ? */
|
/* 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;
|
err = -EINVAL;
|
||||||
goto out_release;
|
goto out_release;
|
||||||
}
|
}
|
||||||
@ -1510,7 +1513,10 @@ static int ax25_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
|
|||||||
struct full_sockaddr_ax25 *fsa = (struct full_sockaddr_ax25 *)usax;
|
struct full_sockaddr_ax25 *fsa = (struct full_sockaddr_ax25 *)usax;
|
||||||
|
|
||||||
/* Valid number of digipeaters ? */
|
/* 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;
|
err = -EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -5252,7 +5252,7 @@ static void flush_backlog(struct work_struct *work)
|
|||||||
skb_queue_walk_safe(&sd->input_pkt_queue, skb, tmp) {
|
skb_queue_walk_safe(&sd->input_pkt_queue, skb, tmp) {
|
||||||
if (skb->dev->reg_state == NETREG_UNREGISTERING) {
|
if (skb->dev->reg_state == NETREG_UNREGISTERING) {
|
||||||
__skb_unlink(skb, &sd->input_pkt_queue);
|
__skb_unlink(skb, &sd->input_pkt_queue);
|
||||||
kfree_skb(skb);
|
dev_kfree_skb_irq(skb);
|
||||||
input_queue_head_incr(sd);
|
input_queue_head_incr(sd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1045,7 +1045,7 @@ static ssize_t tx_timeout_show(struct netdev_queue *queue, char *buf)
|
|||||||
trans_timeout = queue->trans_timeout;
|
trans_timeout = queue->trans_timeout;
|
||||||
spin_unlock_irq(&queue->_xmit_lock);
|
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)
|
static unsigned int get_netdev_queue_index(struct netdev_queue *queue)
|
||||||
|
@ -3146,7 +3146,8 @@ replay:
|
|||||||
*/
|
*/
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
/* If device is not registered at all, free it now */
|
/* 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);
|
free_netdev(dev);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -112,6 +112,7 @@ static struct sock_reuseport *reuseport_grow(struct sock_reuseport *reuse)
|
|||||||
more_reuse->prog = reuse->prog;
|
more_reuse->prog = reuse->prog;
|
||||||
more_reuse->reuseport_id = reuse->reuseport_id;
|
more_reuse->reuseport_id = reuse->reuseport_id;
|
||||||
more_reuse->bind_inany = reuse->bind_inany;
|
more_reuse->bind_inany = reuse->bind_inany;
|
||||||
|
more_reuse->has_conns = reuse->has_conns;
|
||||||
|
|
||||||
memcpy(more_reuse->socks, reuse->socks,
|
memcpy(more_reuse->socks, reuse->socks,
|
||||||
reuse->num_socks * sizeof(struct sock *));
|
reuse->num_socks * sizeof(struct sock *));
|
||||||
|
@ -3489,10 +3489,8 @@ static void tcp_replace_ts_recent(struct tcp_sock *tp, u32 seq)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This routine deals with acks during a TLP episode.
|
/* This routine deals with acks during a TLP episode and ends an episode by
|
||||||
* We mark the end of a TLP episode on receiving TLP dupack or when
|
* resetting tlp_high_seq. Ref: TLP algorithm in draft-ietf-tcpm-rack
|
||||||
* ack is after tlp_high_seq.
|
|
||||||
* Ref: loss detection algorithm in draft-dukkipati-tcpm-tcp-loss-probe.
|
|
||||||
*/
|
*/
|
||||||
static void tcp_process_tlp_ack(struct sock *sk, u32 ack, int flag)
|
static void tcp_process_tlp_ack(struct sock *sk, u32 ack, int flag)
|
||||||
{
|
{
|
||||||
@ -3501,7 +3499,10 @@ static void tcp_process_tlp_ack(struct sock *sk, u32 ack, int flag)
|
|||||||
if (before(ack, tp->tlp_high_seq))
|
if (before(ack, tp->tlp_high_seq))
|
||||||
return;
|
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 */
|
/* This DSACK means original and TLP probe arrived; no loss */
|
||||||
tp->tlp_high_seq = 0;
|
tp->tlp_high_seq = 0;
|
||||||
} else if (after(ack, tp->tlp_high_seq)) {
|
} else if (after(ack, tp->tlp_high_seq)) {
|
||||||
|
@ -2495,6 +2495,11 @@ void tcp_send_loss_probe(struct sock *sk)
|
|||||||
int pcount;
|
int pcount;
|
||||||
int mss = tcp_current_mss(sk);
|
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);
|
skb = tcp_send_head(sk);
|
||||||
if (skb && tcp_snd_wnd_test(tp, skb, mss)) {
|
if (skb && tcp_snd_wnd_test(tp, skb, mss)) {
|
||||||
pcount = tp->packets_out;
|
pcount = tp->packets_out;
|
||||||
@ -2512,10 +2517,6 @@ void tcp_send_loss_probe(struct sock *sk)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* At most one outstanding TLP retransmission. */
|
|
||||||
if (tp->tlp_high_seq)
|
|
||||||
goto rearm_timer;
|
|
||||||
|
|
||||||
if (skb_still_in_host_queue(sk, skb))
|
if (skb_still_in_host_queue(sk, skb))
|
||||||
goto rearm_timer;
|
goto rearm_timer;
|
||||||
|
|
||||||
@ -2537,10 +2538,12 @@ void tcp_send_loss_probe(struct sock *sk)
|
|||||||
if (__tcp_retransmit_skb(sk, skb, 1))
|
if (__tcp_retransmit_skb(sk, skb, 1))
|
||||||
goto rearm_timer;
|
goto rearm_timer;
|
||||||
|
|
||||||
|
tp->tlp_retrans = 1;
|
||||||
|
|
||||||
|
probe_sent:
|
||||||
/* Record snd_nxt for loss detection. */
|
/* Record snd_nxt for loss detection. */
|
||||||
tp->tlp_high_seq = tp->snd_nxt;
|
tp->tlp_high_seq = tp->snd_nxt;
|
||||||
|
|
||||||
probe_sent:
|
|
||||||
NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPLOSSPROBES);
|
NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPLOSSPROBES);
|
||||||
/* Reset s.t. tcp_rearm_rto will restart timer from now */
|
/* Reset s.t. tcp_rearm_rto will restart timer from now */
|
||||||
inet_csk(sk)->icsk_pending = 0;
|
inet_csk(sk)->icsk_pending = 0;
|
||||||
|
@ -433,7 +433,7 @@ static struct sock *udp4_lib_lookup2(struct net *net,
|
|||||||
struct udp_hslot *hslot2,
|
struct udp_hslot *hslot2,
|
||||||
struct sk_buff *skb)
|
struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct sock *sk, *result;
|
struct sock *sk, *result, *reuseport_result;
|
||||||
int score, badness;
|
int score, badness;
|
||||||
u32 hash = 0;
|
u32 hash = 0;
|
||||||
|
|
||||||
@ -443,17 +443,20 @@ static struct sock *udp4_lib_lookup2(struct net *net,
|
|||||||
score = compute_score(sk, net, saddr, sport,
|
score = compute_score(sk, net, saddr, sport,
|
||||||
daddr, hnum, dif, sdif, exact_dif);
|
daddr, hnum, dif, sdif, exact_dif);
|
||||||
if (score > badness) {
|
if (score > badness) {
|
||||||
|
reuseport_result = NULL;
|
||||||
|
|
||||||
if (sk->sk_reuseport &&
|
if (sk->sk_reuseport &&
|
||||||
sk->sk_state != TCP_ESTABLISHED) {
|
sk->sk_state != TCP_ESTABLISHED) {
|
||||||
hash = udp_ehashfn(net, daddr, hnum,
|
hash = udp_ehashfn(net, daddr, hnum,
|
||||||
saddr, sport);
|
saddr, sport);
|
||||||
result = reuseport_select_sock(sk, hash, skb,
|
reuseport_result = reuseport_select_sock(sk, hash, skb,
|
||||||
sizeof(struct udphdr));
|
sizeof(struct udphdr));
|
||||||
if (result && !reuseport_has_conns(sk, false))
|
if (reuseport_result && !reuseport_has_conns(sk, false))
|
||||||
return result;
|
return reuseport_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result = reuseport_result ? : sk;
|
||||||
badness = score;
|
badness = score;
|
||||||
result = sk;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -1986,7 +1989,7 @@ static int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
|
|||||||
/*
|
/*
|
||||||
* UDP-Lite specific tests, ignored on UDP sockets
|
* 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
|
* MIB statistics other than incrementing the error count are
|
||||||
|
@ -1580,17 +1580,18 @@ static void ip6gre_destroy_tunnels(struct net *net, struct list_head *head)
|
|||||||
static int __net_init ip6gre_init_net(struct net *net)
|
static int __net_init ip6gre_init_net(struct net *net)
|
||||||
{
|
{
|
||||||
struct ip6gre_net *ign = net_generic(net, ip6gre_net_id);
|
struct ip6gre_net *ign = net_generic(net, ip6gre_net_id);
|
||||||
|
struct net_device *ndev;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!net_has_fallback_tunnels(net))
|
if (!net_has_fallback_tunnels(net))
|
||||||
return 0;
|
return 0;
|
||||||
ign->fb_tunnel_dev = alloc_netdev(sizeof(struct ip6_tnl), "ip6gre0",
|
ndev = alloc_netdev(sizeof(struct ip6_tnl), "ip6gre0",
|
||||||
NET_NAME_UNKNOWN,
|
NET_NAME_UNKNOWN, ip6gre_tunnel_setup);
|
||||||
ip6gre_tunnel_setup);
|
if (!ndev) {
|
||||||
if (!ign->fb_tunnel_dev) {
|
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
goto err_alloc_dev;
|
goto err_alloc_dev;
|
||||||
}
|
}
|
||||||
|
ign->fb_tunnel_dev = ndev;
|
||||||
dev_net_set(ign->fb_tunnel_dev, net);
|
dev_net_set(ign->fb_tunnel_dev, net);
|
||||||
/* FB netdevice is special: we have one, and only one per netns.
|
/* FB netdevice is special: we have one, and only one per netns.
|
||||||
* Allowing to move it to another netns is clearly unsafe.
|
* Allowing to move it to another netns is clearly unsafe.
|
||||||
@ -1610,7 +1611,7 @@ static int __net_init ip6gre_init_net(struct net *net)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_reg_dev:
|
err_reg_dev:
|
||||||
free_netdev(ign->fb_tunnel_dev);
|
free_netdev(ndev);
|
||||||
err_alloc_dev:
|
err_alloc_dev:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -167,7 +167,7 @@ static struct sock *udp6_lib_lookup2(struct net *net,
|
|||||||
int dif, int sdif, bool exact_dif,
|
int dif, int sdif, bool exact_dif,
|
||||||
struct udp_hslot *hslot2, struct sk_buff *skb)
|
struct udp_hslot *hslot2, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct sock *sk, *result;
|
struct sock *sk, *result, *reuseport_result;
|
||||||
int score, badness;
|
int score, badness;
|
||||||
u32 hash = 0;
|
u32 hash = 0;
|
||||||
|
|
||||||
@ -177,17 +177,20 @@ static struct sock *udp6_lib_lookup2(struct net *net,
|
|||||||
score = compute_score(sk, net, saddr, sport,
|
score = compute_score(sk, net, saddr, sport,
|
||||||
daddr, hnum, dif, sdif, exact_dif);
|
daddr, hnum, dif, sdif, exact_dif);
|
||||||
if (score > badness) {
|
if (score > badness) {
|
||||||
|
reuseport_result = NULL;
|
||||||
|
|
||||||
if (sk->sk_reuseport &&
|
if (sk->sk_reuseport &&
|
||||||
sk->sk_state != TCP_ESTABLISHED) {
|
sk->sk_state != TCP_ESTABLISHED) {
|
||||||
hash = udp6_ehashfn(net, daddr, hnum,
|
hash = udp6_ehashfn(net, daddr, hnum,
|
||||||
saddr, sport);
|
saddr, sport);
|
||||||
|
|
||||||
result = reuseport_select_sock(sk, hash, skb,
|
reuseport_result = reuseport_select_sock(sk, hash, skb,
|
||||||
sizeof(struct udphdr));
|
sizeof(struct udphdr));
|
||||||
if (result && !reuseport_has_conns(sk, false))
|
if (reuseport_result && !reuseport_has_conns(sk, false))
|
||||||
return result;
|
return reuseport_result;
|
||||||
}
|
}
|
||||||
result = sk;
|
|
||||||
|
result = reuseport_result ? : sk;
|
||||||
badness = score;
|
badness = score;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -606,7 +609,7 @@ static int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
|
|||||||
/*
|
/*
|
||||||
* UDP-Lite specific tests, ignored on UDP sockets (see net/ipv4/udp.c).
|
* 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 */
|
if (up->pcrlen == 0) { /* full coverage was set */
|
||||||
net_dbg_ratelimited("UDPLITE6: partial coverage %d while full coverage %d requested\n",
|
net_dbg_ratelimited("UDPLITE6: partial coverage %d while full coverage %d requested\n",
|
||||||
|
@ -1013,6 +1013,7 @@ static int qrtr_release(struct socket *sock)
|
|||||||
sk->sk_state_change(sk);
|
sk->sk_state_change(sk);
|
||||||
|
|
||||||
sock_set_flag(sk, SOCK_DEAD);
|
sock_set_flag(sk, SOCK_DEAD);
|
||||||
|
sock_orphan(sk);
|
||||||
sock->sk = NULL;
|
sock->sk = NULL;
|
||||||
|
|
||||||
if (!sock_flag(sk, SOCK_ZAPPED))
|
if (!sock_flag(sk, SOCK_ZAPPED))
|
||||||
|
@ -453,7 +453,7 @@ try_again:
|
|||||||
list_empty(&rx->recvmsg_q) &&
|
list_empty(&rx->recvmsg_q) &&
|
||||||
rx->sk.sk_state != RXRPC_SERVER_LISTENING) {
|
rx->sk.sk_state != RXRPC_SERVER_LISTENING) {
|
||||||
release_sock(&rx->sk);
|
release_sock(&rx->sk);
|
||||||
return -ENODATA;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (list_empty(&rx->recvmsg_q)) {
|
if (list_empty(&rx->recvmsg_q)) {
|
||||||
|
@ -278,7 +278,7 @@ static int rxrpc_send_data(struct rxrpc_sock *rx,
|
|||||||
/* this should be in poll */
|
/* this should be in poll */
|
||||||
sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk);
|
sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk);
|
||||||
|
|
||||||
if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))
|
if (sk->sk_shutdown & SEND_SHUTDOWN)
|
||||||
return -EPIPE;
|
return -EPIPE;
|
||||||
|
|
||||||
more = msg->msg_flags & MSG_MORE;
|
more = msg->msg_flags & MSG_MORE;
|
||||||
|
@ -97,17 +97,11 @@ static size_t fa_index(struct flex_array *fa, void *elem, size_t count)
|
|||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Migrates chunks from stream queues to new stream queues if needed,
|
static void sctp_stream_shrink_out(struct sctp_stream *stream, __u16 outcnt)
|
||||||
* 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)
|
|
||||||
{
|
{
|
||||||
struct sctp_association *asoc;
|
struct sctp_association *asoc;
|
||||||
struct sctp_chunk *ch, *temp;
|
struct sctp_chunk *ch, *temp;
|
||||||
struct sctp_outq *outq;
|
struct sctp_outq *outq;
|
||||||
int i;
|
|
||||||
|
|
||||||
asoc = container_of(stream, struct sctp_association, stream);
|
asoc = container_of(stream, struct sctp_association, stream);
|
||||||
outq = &asoc->outqueue;
|
outq = &asoc->outqueue;
|
||||||
@ -131,6 +125,19 @@ static void sctp_stream_outq_migrate(struct sctp_stream *stream,
|
|||||||
|
|
||||||
sctp_chunk_free(ch);
|
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) {
|
if (new) {
|
||||||
/* Here we actually move the old ext stuff into the new
|
/* Here we actually move the old ext stuff into the new
|
||||||
@ -1136,11 +1143,13 @@ struct sctp_chunk *sctp_process_strreset_resp(
|
|||||||
nums = ntohs(addstrm->number_of_streams);
|
nums = ntohs(addstrm->number_of_streams);
|
||||||
number = stream->outcnt - nums;
|
number = stream->outcnt - nums;
|
||||||
|
|
||||||
if (result == SCTP_STRRESET_PERFORMED)
|
if (result == SCTP_STRRESET_PERFORMED) {
|
||||||
for (i = number; i < stream->outcnt; i++)
|
for (i = number; i < stream->outcnt; i++)
|
||||||
SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;
|
SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;
|
||||||
else
|
} else {
|
||||||
|
sctp_stream_shrink_out(stream, number);
|
||||||
stream->outcnt = number;
|
stream->outcnt = number;
|
||||||
|
}
|
||||||
|
|
||||||
*evp = sctp_ulpevent_make_stream_change_event(asoc, flags,
|
*evp = sctp_ulpevent_make_stream_change_event(asoc, flags,
|
||||||
0, nums, GFP_ATOMIC);
|
0, nums, GFP_ATOMIC);
|
||||||
|
Loading…
Reference in New Issue
Block a user