aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_input.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-07-23 02:44:31 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-07-23 02:44:31 -0400
commit107df03203bb66de56e2caec3bde6d22b55480c5 (patch)
treecff42c091a4a9f43203bbb85c9cf526857470a8f /net/ipv4/tcp_input.c
parent88083e9845612826dfd44a5215647b4f6567317c (diff)
parentf8e7718cc0445587fe8530fc2d240d9aac2c9072 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller: 1) Fix memory leak in nftables, from Liping Zhang. 2) Need to check result of vlan_insert_tag() in batman-adv otherwise we risk NULL skb derefs, from Sven Eckelmann. 3) Check for dev_alloc_skb() failures in cfg80211, from Gregory Greenman. 4) Handle properly when we have ppp_unregister_channel() happening in parallel with ppp_connect_channel(), from WANG Cong. 5) Fix DCCP deadlock, from Eric Dumazet. 6) Bail out properly in UDP if sk_filter() truncates the packet to be smaller than even the space that the protocol headers need. From Michal Kubecek. 7) Similarly for rose, dccp, and sctp, from Willem de Bruijn. 8) Make TCP challenge ACKs less predictable, from Eric Dumazet. 9) Fix infinite loop in bgmac_dma_tx_add() from Florian Fainelli. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (65 commits) packet: propagate sock_cmsg_send() error net/mlx5e: Fix del vxlan port command buffer memset packet: fix second argument of sock_tx_timestamp() net: switchdev: change ageing_time type to clock_t Update maintainer for EHEA driver. net/mlx4_en: Add resilience in low memory systems net/mlx4_en: Move filters cleanup to a proper location sctp: load transport header after sk_filter net/sched/sch_htb: clamp xstats tokens to fit into 32-bit int net: cavium: liquidio: Avoid dma_unmap_single on uninitialized ndata net: nb8800: Fix SKB leak in nb8800_receive() et131x: Fix logical vs bitwise check in et131x_tx_timeout() vlan: use a valid default mtu value for vlan over macsec net: bgmac: Fix infinite loop in bgmac_dma_tx_add() mlxsw: spectrum: Prevent invalid ingress buffer mapping mlxsw: spectrum: Prevent overwrite of DCB capability fields mlxsw: spectrum: Don't emit errors when PFC is disabled mlxsw: spectrum: Indicate support for autonegotiation mlxsw: spectrum: Force link training according to admin state r8152: add MODULE_VERSION ...
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r--net/ipv4/tcp_input.c54
1 files changed, 32 insertions, 22 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index d6c8f4cd0800..42bf89aaf6a5 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -87,7 +87,7 @@ int sysctl_tcp_adv_win_scale __read_mostly = 1;
87EXPORT_SYMBOL(sysctl_tcp_adv_win_scale); 87EXPORT_SYMBOL(sysctl_tcp_adv_win_scale);
88 88
89/* rfc5961 challenge ack rate limiting */ 89/* rfc5961 challenge ack rate limiting */
90int sysctl_tcp_challenge_ack_limit = 100; 90int sysctl_tcp_challenge_ack_limit = 1000;
91 91
92int sysctl_tcp_stdurg __read_mostly; 92int sysctl_tcp_stdurg __read_mostly;
93int sysctl_tcp_rfc1337 __read_mostly; 93int sysctl_tcp_rfc1337 __read_mostly;
@@ -3421,6 +3421,23 @@ static int tcp_ack_update_window(struct sock *sk, const struct sk_buff *skb, u32
3421 return flag; 3421 return flag;
3422} 3422}
3423 3423
3424static bool __tcp_oow_rate_limited(struct net *net, int mib_idx,
3425 u32 *last_oow_ack_time)
3426{
3427 if (*last_oow_ack_time) {
3428 s32 elapsed = (s32)(tcp_time_stamp - *last_oow_ack_time);
3429
3430 if (0 <= elapsed && elapsed < sysctl_tcp_invalid_ratelimit) {
3431 NET_INC_STATS(net, mib_idx);
3432 return true; /* rate-limited: don't send yet! */
3433 }
3434 }
3435
3436 *last_oow_ack_time = tcp_time_stamp;
3437
3438 return false; /* not rate-limited: go ahead, send dupack now! */
3439}
3440
3424/* Return true if we're currently rate-limiting out-of-window ACKs and 3441/* Return true if we're currently rate-limiting out-of-window ACKs and
3425 * thus shouldn't send a dupack right now. We rate-limit dupacks in 3442 * thus shouldn't send a dupack right now. We rate-limit dupacks in
3426 * response to out-of-window SYNs or ACKs to mitigate ACK loops or DoS 3443 * response to out-of-window SYNs or ACKs to mitigate ACK loops or DoS
@@ -3434,21 +3451,9 @@ bool tcp_oow_rate_limited(struct net *net, const struct sk_buff *skb,
3434 /* Data packets without SYNs are not likely part of an ACK loop. */ 3451 /* Data packets without SYNs are not likely part of an ACK loop. */
3435 if ((TCP_SKB_CB(skb)->seq != TCP_SKB_CB(skb)->end_seq) && 3452 if ((TCP_SKB_CB(skb)->seq != TCP_SKB_CB(skb)->end_seq) &&
3436 !tcp_hdr(skb)->syn) 3453 !tcp_hdr(skb)->syn)
3437 goto not_rate_limited; 3454 return false;
3438
3439 if (*last_oow_ack_time) {
3440 s32 elapsed = (s32)(tcp_time_stamp - *last_oow_ack_time);
3441
3442 if (0 <= elapsed && elapsed < sysctl_tcp_invalid_ratelimit) {
3443 NET_INC_STATS(net, mib_idx);
3444 return true; /* rate-limited: don't send yet! */
3445 }
3446 }
3447
3448 *last_oow_ack_time = tcp_time_stamp;
3449 3455
3450not_rate_limited: 3456 return __tcp_oow_rate_limited(net, mib_idx, last_oow_ack_time);
3451 return false; /* not rate-limited: go ahead, send dupack now! */
3452} 3457}
3453 3458
3454/* RFC 5961 7 [ACK Throttling] */ 3459/* RFC 5961 7 [ACK Throttling] */
@@ -3458,21 +3463,26 @@ static void tcp_send_challenge_ack(struct sock *sk, const struct sk_buff *skb)
3458 static u32 challenge_timestamp; 3463 static u32 challenge_timestamp;
3459 static unsigned int challenge_count; 3464 static unsigned int challenge_count;
3460 struct tcp_sock *tp = tcp_sk(sk); 3465 struct tcp_sock *tp = tcp_sk(sk);
3461 u32 now; 3466 u32 count, now;
3462 3467
3463 /* First check our per-socket dupack rate limit. */ 3468 /* First check our per-socket dupack rate limit. */
3464 if (tcp_oow_rate_limited(sock_net(sk), skb, 3469 if (__tcp_oow_rate_limited(sock_net(sk),
3465 LINUX_MIB_TCPACKSKIPPEDCHALLENGE, 3470 LINUX_MIB_TCPACKSKIPPEDCHALLENGE,
3466 &tp->last_oow_ack_time)) 3471 &tp->last_oow_ack_time))
3467 return; 3472 return;
3468 3473
3469 /* Then check the check host-wide RFC 5961 rate limit. */ 3474 /* Then check host-wide RFC 5961 rate limit. */
3470 now = jiffies / HZ; 3475 now = jiffies / HZ;
3471 if (now != challenge_timestamp) { 3476 if (now != challenge_timestamp) {
3477 u32 half = (sysctl_tcp_challenge_ack_limit + 1) >> 1;
3478
3472 challenge_timestamp = now; 3479 challenge_timestamp = now;
3473 challenge_count = 0; 3480 WRITE_ONCE(challenge_count, half +
3481 prandom_u32_max(sysctl_tcp_challenge_ack_limit));
3474 } 3482 }
3475 if (++challenge_count <= sysctl_tcp_challenge_ack_limit) { 3483 count = READ_ONCE(challenge_count);
3484 if (count > 0) {
3485 WRITE_ONCE(challenge_count, count - 1);
3476 NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPCHALLENGEACK); 3486 NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPCHALLENGEACK);
3477 tcp_send_ack(sk); 3487 tcp_send_ack(sk);
3478 } 3488 }