Contents of /trunk/kernel-alx/patches-4.9/0281-4.9.182-all-fixes.patch
Parent Directory | Revision Log
Revision 3358 -
(show annotations)
(download)
Tue Jun 18 09:42:10 2019 UTC (5 years, 3 months ago) by niro
File size: 9198 byte(s)
Tue Jun 18 09:42:10 2019 UTC (5 years, 3 months ago) by niro
File size: 9198 byte(s)
-linux-4.9.182
1 | diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt |
2 | index 0335285f3918..49935d5bb5c6 100644 |
3 | --- a/Documentation/networking/ip-sysctl.txt |
4 | +++ b/Documentation/networking/ip-sysctl.txt |
5 | @@ -230,6 +230,14 @@ tcp_base_mss - INTEGER |
6 | Path MTU discovery (MTU probing). If MTU probing is enabled, |
7 | this is the initial MSS used by the connection. |
8 | |
9 | +tcp_min_snd_mss - INTEGER |
10 | + TCP SYN and SYNACK messages usually advertise an ADVMSS option, |
11 | + as described in RFC 1122 and RFC 6691. |
12 | + If this ADVMSS option is smaller than tcp_min_snd_mss, |
13 | + it is silently capped to tcp_min_snd_mss. |
14 | + |
15 | + Default : 48 (at least 8 bytes of payload per segment) |
16 | + |
17 | tcp_congestion_control - STRING |
18 | Set the congestion control algorithm to be used for new |
19 | connections. The algorithm "reno" is always available, but |
20 | diff --git a/Makefile b/Makefile |
21 | index 584af2e57735..f34cb9225255 100644 |
22 | --- a/Makefile |
23 | +++ b/Makefile |
24 | @@ -1,6 +1,6 @@ |
25 | VERSION = 4 |
26 | PATCHLEVEL = 9 |
27 | -SUBLEVEL = 181 |
28 | +SUBLEVEL = 182 |
29 | EXTRAVERSION = |
30 | NAME = Roaring Lionus |
31 | |
32 | diff --git a/include/linux/tcp.h b/include/linux/tcp.h |
33 | index d0c3615f9050..7f517458c64f 100644 |
34 | --- a/include/linux/tcp.h |
35 | +++ b/include/linux/tcp.h |
36 | @@ -433,4 +433,7 @@ static inline void tcp_saved_syn_free(struct tcp_sock *tp) |
37 | tp->saved_syn = NULL; |
38 | } |
39 | |
40 | +int tcp_skb_shift(struct sk_buff *to, struct sk_buff *from, int pcount, |
41 | + int shiftlen); |
42 | + |
43 | #endif /* _LINUX_TCP_H */ |
44 | diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h |
45 | index 7adf4386ac8f..bf619a67ec03 100644 |
46 | --- a/include/net/netns/ipv4.h |
47 | +++ b/include/net/netns/ipv4.h |
48 | @@ -94,6 +94,7 @@ struct netns_ipv4 { |
49 | #endif |
50 | int sysctl_tcp_mtu_probing; |
51 | int sysctl_tcp_base_mss; |
52 | + int sysctl_tcp_min_snd_mss; |
53 | int sysctl_tcp_probe_threshold; |
54 | u32 sysctl_tcp_probe_interval; |
55 | |
56 | diff --git a/include/net/tcp.h b/include/net/tcp.h |
57 | index fed2a78fb8cb..d7047de952f0 100644 |
58 | --- a/include/net/tcp.h |
59 | +++ b/include/net/tcp.h |
60 | @@ -53,6 +53,8 @@ void tcp_time_wait(struct sock *sk, int state, int timeo); |
61 | |
62 | #define MAX_TCP_HEADER (128 + MAX_HEADER) |
63 | #define MAX_TCP_OPTION_SPACE 40 |
64 | +#define TCP_MIN_SND_MSS 48 |
65 | +#define TCP_MIN_GSO_SIZE (TCP_MIN_SND_MSS - MAX_TCP_OPTION_SPACE) |
66 | |
67 | /* |
68 | * Never offer a window over 32767 without using window scaling. Some |
69 | diff --git a/include/uapi/linux/snmp.h b/include/uapi/linux/snmp.h |
70 | index 3442a26d36d9..56e3460d1f9f 100644 |
71 | --- a/include/uapi/linux/snmp.h |
72 | +++ b/include/uapi/linux/snmp.h |
73 | @@ -282,6 +282,7 @@ enum |
74 | LINUX_MIB_TCPKEEPALIVE, /* TCPKeepAlive */ |
75 | LINUX_MIB_TCPMTUPFAIL, /* TCPMTUPFail */ |
76 | LINUX_MIB_TCPMTUPSUCCESS, /* TCPMTUPSuccess */ |
77 | + LINUX_MIB_TCPWQUEUETOOBIG, /* TCPWqueueTooBig */ |
78 | __LINUX_MIB_MAX |
79 | }; |
80 | |
81 | diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c |
82 | index ec48d8eafc7e..8b221398534b 100644 |
83 | --- a/net/ipv4/proc.c |
84 | +++ b/net/ipv4/proc.c |
85 | @@ -306,6 +306,7 @@ static const struct snmp_mib snmp4_net_list[] = { |
86 | SNMP_MIB_ITEM("TCPKeepAlive", LINUX_MIB_TCPKEEPALIVE), |
87 | SNMP_MIB_ITEM("TCPMTUPFail", LINUX_MIB_TCPMTUPFAIL), |
88 | SNMP_MIB_ITEM("TCPMTUPSuccess", LINUX_MIB_TCPMTUPSUCCESS), |
89 | + SNMP_MIB_ITEM("TCPWqueueTooBig", LINUX_MIB_TCPWQUEUETOOBIG), |
90 | SNMP_MIB_SENTINEL |
91 | }; |
92 | |
93 | diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c |
94 | index 85713adf2770..e202babb14d6 100644 |
95 | --- a/net/ipv4/sysctl_net_ipv4.c |
96 | +++ b/net/ipv4/sysctl_net_ipv4.c |
97 | @@ -35,6 +35,8 @@ static int ip_local_port_range_min[] = { 1, 1 }; |
98 | static int ip_local_port_range_max[] = { 65535, 65535 }; |
99 | static int tcp_adv_win_scale_min = -31; |
100 | static int tcp_adv_win_scale_max = 31; |
101 | +static int tcp_min_snd_mss_min = TCP_MIN_SND_MSS; |
102 | +static int tcp_min_snd_mss_max = 65535; |
103 | static int ip_ttl_min = 1; |
104 | static int ip_ttl_max = 255; |
105 | static int tcp_syn_retries_min = 1; |
106 | @@ -838,6 +840,15 @@ static struct ctl_table ipv4_net_table[] = { |
107 | .mode = 0644, |
108 | .proc_handler = proc_dointvec, |
109 | }, |
110 | + { |
111 | + .procname = "tcp_min_snd_mss", |
112 | + .data = &init_net.ipv4.sysctl_tcp_min_snd_mss, |
113 | + .maxlen = sizeof(int), |
114 | + .mode = 0644, |
115 | + .proc_handler = proc_dointvec_minmax, |
116 | + .extra1 = &tcp_min_snd_mss_min, |
117 | + .extra2 = &tcp_min_snd_mss_max, |
118 | + }, |
119 | { |
120 | .procname = "tcp_probe_threshold", |
121 | .data = &init_net.ipv4.sysctl_tcp_probe_threshold, |
122 | diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c |
123 | index 2ededb32b754..ee2822a411f9 100644 |
124 | --- a/net/ipv4/tcp.c |
125 | +++ b/net/ipv4/tcp.c |
126 | @@ -3307,6 +3307,7 @@ void __init tcp_init(void) |
127 | unsigned long limit; |
128 | unsigned int i; |
129 | |
130 | + BUILD_BUG_ON(TCP_MIN_SND_MSS <= MAX_TCP_OPTION_SPACE); |
131 | BUILD_BUG_ON(sizeof(struct tcp_skb_cb) > |
132 | FIELD_SIZEOF(struct sk_buff, cb)); |
133 | |
134 | diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c |
135 | index e238539c3497..e2e58bc42ba4 100644 |
136 | --- a/net/ipv4/tcp_input.c |
137 | +++ b/net/ipv4/tcp_input.c |
138 | @@ -1320,7 +1320,7 @@ static bool tcp_shifted_skb(struct sock *sk, struct sk_buff *skb, |
139 | TCP_SKB_CB(skb)->seq += shifted; |
140 | |
141 | tcp_skb_pcount_add(prev, pcount); |
142 | - BUG_ON(tcp_skb_pcount(skb) < pcount); |
143 | + WARN_ON_ONCE(tcp_skb_pcount(skb) < pcount); |
144 | tcp_skb_pcount_add(skb, -pcount); |
145 | |
146 | /* When we're adding to gso_segs == 1, gso_size will be zero, |
147 | @@ -1387,6 +1387,21 @@ static int skb_can_shift(const struct sk_buff *skb) |
148 | return !skb_headlen(skb) && skb_is_nonlinear(skb); |
149 | } |
150 | |
151 | +int tcp_skb_shift(struct sk_buff *to, struct sk_buff *from, |
152 | + int pcount, int shiftlen) |
153 | +{ |
154 | + /* TCP min gso_size is 8 bytes (TCP_MIN_GSO_SIZE) |
155 | + * Since TCP_SKB_CB(skb)->tcp_gso_segs is 16 bits, we need |
156 | + * to make sure not storing more than 65535 * 8 bytes per skb, |
157 | + * even if current MSS is bigger. |
158 | + */ |
159 | + if (unlikely(to->len + shiftlen >= 65535 * TCP_MIN_GSO_SIZE)) |
160 | + return 0; |
161 | + if (unlikely(tcp_skb_pcount(to) + pcount > 65535)) |
162 | + return 0; |
163 | + return skb_shift(to, from, shiftlen); |
164 | +} |
165 | + |
166 | /* Try collapsing SACK blocks spanning across multiple skbs to a single |
167 | * skb. |
168 | */ |
169 | @@ -1398,6 +1413,7 @@ static struct sk_buff *tcp_shift_skb_data(struct sock *sk, struct sk_buff *skb, |
170 | struct tcp_sock *tp = tcp_sk(sk); |
171 | struct sk_buff *prev; |
172 | int mss; |
173 | + int next_pcount; |
174 | int pcount = 0; |
175 | int len; |
176 | int in_sack; |
177 | @@ -1495,7 +1511,7 @@ static struct sk_buff *tcp_shift_skb_data(struct sock *sk, struct sk_buff *skb, |
178 | if (!after(TCP_SKB_CB(skb)->seq + len, tp->snd_una)) |
179 | goto fallback; |
180 | |
181 | - if (!skb_shift(prev, skb, len)) |
182 | + if (!tcp_skb_shift(prev, skb, pcount, len)) |
183 | goto fallback; |
184 | if (!tcp_shifted_skb(sk, skb, state, pcount, len, mss, dup_sack)) |
185 | goto out; |
186 | @@ -1514,11 +1530,11 @@ static struct sk_buff *tcp_shift_skb_data(struct sock *sk, struct sk_buff *skb, |
187 | goto out; |
188 | |
189 | len = skb->len; |
190 | - if (skb_shift(prev, skb, len)) { |
191 | - pcount += tcp_skb_pcount(skb); |
192 | - tcp_shifted_skb(sk, skb, state, tcp_skb_pcount(skb), len, mss, 0); |
193 | + next_pcount = tcp_skb_pcount(skb); |
194 | + if (tcp_skb_shift(prev, skb, next_pcount, len)) { |
195 | + pcount += next_pcount; |
196 | + tcp_shifted_skb(sk, skb, state, next_pcount, len, mss, 0); |
197 | } |
198 | - |
199 | out: |
200 | state->fack_count += pcount; |
201 | return prev; |
202 | @@ -2837,9 +2853,9 @@ static void tcp_fastretrans_alert(struct sock *sk, const int acked, |
203 | bool do_lost = is_dupack || ((flag & FLAG_DATA_SACKED) && |
204 | (tcp_fackets_out(tp) > tp->reordering)); |
205 | |
206 | - if (WARN_ON(!tp->packets_out && tp->sacked_out)) |
207 | + if (!tp->packets_out && tp->sacked_out) |
208 | tp->sacked_out = 0; |
209 | - if (WARN_ON(!tp->sacked_out && tp->fackets_out)) |
210 | + if (!tp->sacked_out && tp->fackets_out) |
211 | tp->fackets_out = 0; |
212 | |
213 | /* Now state machine starts. |
214 | diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c |
215 | index 82c1064ff4aa..848f2c1da8a5 100644 |
216 | --- a/net/ipv4/tcp_ipv4.c |
217 | +++ b/net/ipv4/tcp_ipv4.c |
218 | @@ -2456,6 +2456,7 @@ static int __net_init tcp_sk_init(struct net *net) |
219 | net->ipv4.sysctl_tcp_ecn_fallback = 1; |
220 | |
221 | net->ipv4.sysctl_tcp_base_mss = TCP_BASE_MSS; |
222 | + net->ipv4.sysctl_tcp_min_snd_mss = TCP_MIN_SND_MSS; |
223 | net->ipv4.sysctl_tcp_probe_threshold = TCP_PROBE_THRESHOLD; |
224 | net->ipv4.sysctl_tcp_probe_interval = TCP_PROBE_INTERVAL; |
225 | |
226 | diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c |
227 | index 6f35cdd5f2f0..d8c6b833f0ce 100644 |
228 | --- a/net/ipv4/tcp_output.c |
229 | +++ b/net/ipv4/tcp_output.c |
230 | @@ -1185,6 +1185,11 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, |
231 | if (nsize < 0) |
232 | nsize = 0; |
233 | |
234 | + if (unlikely((sk->sk_wmem_queued >> 1) > sk->sk_sndbuf)) { |
235 | + NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPWQUEUETOOBIG); |
236 | + return -ENOMEM; |
237 | + } |
238 | + |
239 | if (skb_unclone(skb, gfp)) |
240 | return -ENOMEM; |
241 | |
242 | @@ -1355,8 +1360,7 @@ static inline int __tcp_mtu_to_mss(struct sock *sk, int pmtu) |
243 | mss_now -= icsk->icsk_ext_hdr_len; |
244 | |
245 | /* Then reserve room for full set of TCP options and 8 bytes of data */ |
246 | - if (mss_now < 48) |
247 | - mss_now = 48; |
248 | + mss_now = max(mss_now, sock_net(sk)->ipv4.sysctl_tcp_min_snd_mss); |
249 | return mss_now; |
250 | } |
251 | |
252 | diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c |
253 | index 69523389f067..d9e364c4863a 100644 |
254 | --- a/net/ipv4/tcp_timer.c |
255 | +++ b/net/ipv4/tcp_timer.c |
256 | @@ -140,6 +140,7 @@ static void tcp_mtu_probing(struct inet_connection_sock *icsk, struct sock *sk) |
257 | mss = tcp_mtu_to_mss(sk, icsk->icsk_mtup.search_low) >> 1; |
258 | mss = min(net->ipv4.sysctl_tcp_base_mss, mss); |
259 | mss = max(mss, 68 - tp->tcp_header_len); |
260 | + mss = max(mss, net->ipv4.sysctl_tcp_min_snd_mss); |
261 | icsk->icsk_mtup.search_low = tcp_mss_to_mtu(sk, mss); |
262 | tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); |
263 | } |