aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/ip_sockglue.c35
-rw-r--r--net/ipv4/ip_vti.c5
-rw-r--r--net/ipv4/tcp.c4
-rw-r--r--net/ipv4/tcp_input.c15
-rw-r--r--net/ipv4/tcp_metrics.c12
-rw-r--r--net/ipv4/tcp_output.c4
6 files changed, 52 insertions, 23 deletions
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 5eea4a811042..14bbfcf717ac 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -457,19 +457,28 @@ static int do_ip_setsockopt(struct sock *sk, int level,
457 struct inet_sock *inet = inet_sk(sk); 457 struct inet_sock *inet = inet_sk(sk);
458 int val = 0, err; 458 int val = 0, err;
459 459
460 if (((1<<optname) & ((1<<IP_PKTINFO) | (1<<IP_RECVTTL) | 460 switch (optname) {
461 (1<<IP_RECVOPTS) | (1<<IP_RECVTOS) | 461 case IP_PKTINFO:
462 (1<<IP_RETOPTS) | (1<<IP_TOS) | 462 case IP_RECVTTL:
463 (1<<IP_TTL) | (1<<IP_HDRINCL) | 463 case IP_RECVOPTS:
464 (1<<IP_MTU_DISCOVER) | (1<<IP_RECVERR) | 464 case IP_RECVTOS:
465 (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) | 465 case IP_RETOPTS:
466 (1<<IP_PASSSEC) | (1<<IP_TRANSPARENT) | 466 case IP_TOS:
467 (1<<IP_MINTTL) | (1<<IP_NODEFRAG))) || 467 case IP_TTL:
468 optname == IP_UNICAST_IF || 468 case IP_HDRINCL:
469 optname == IP_MULTICAST_TTL || 469 case IP_MTU_DISCOVER:
470 optname == IP_MULTICAST_ALL || 470 case IP_RECVERR:
471 optname == IP_MULTICAST_LOOP || 471 case IP_ROUTER_ALERT:
472 optname == IP_RECVORIGDSTADDR) { 472 case IP_FREEBIND:
473 case IP_PASSSEC:
474 case IP_TRANSPARENT:
475 case IP_MINTTL:
476 case IP_NODEFRAG:
477 case IP_UNICAST_IF:
478 case IP_MULTICAST_TTL:
479 case IP_MULTICAST_ALL:
480 case IP_MULTICAST_LOOP:
481 case IP_RECVORIGDSTADDR:
473 if (optlen >= sizeof(int)) { 482 if (optlen >= sizeof(int)) {
474 if (get_user(val, (int __user *) optval)) 483 if (get_user(val, (int __user *) optval))
475 return -EFAULT; 484 return -EFAULT;
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c
index 1831092f999f..858fddf6482a 100644
--- a/net/ipv4/ip_vti.c
+++ b/net/ipv4/ip_vti.c
@@ -338,12 +338,17 @@ static int vti_rcv(struct sk_buff *skb)
338 if (tunnel != NULL) { 338 if (tunnel != NULL) {
339 struct pcpu_tstats *tstats; 339 struct pcpu_tstats *tstats;
340 340
341 if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
342 return -1;
343
341 tstats = this_cpu_ptr(tunnel->dev->tstats); 344 tstats = this_cpu_ptr(tunnel->dev->tstats);
342 u64_stats_update_begin(&tstats->syncp); 345 u64_stats_update_begin(&tstats->syncp);
343 tstats->rx_packets++; 346 tstats->rx_packets++;
344 tstats->rx_bytes += skb->len; 347 tstats->rx_bytes += skb->len;
345 u64_stats_update_end(&tstats->syncp); 348 u64_stats_update_end(&tstats->syncp);
346 349
350 skb->mark = 0;
351 secpath_reset(skb);
347 skb->dev = tunnel->dev; 352 skb->dev = tunnel->dev;
348 return 1; 353 return 1;
349 } 354 }
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 197c0008503c..083092e3aed6 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1212,7 +1212,7 @@ new_segment:
1212wait_for_sndbuf: 1212wait_for_sndbuf:
1213 set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); 1213 set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
1214wait_for_memory: 1214wait_for_memory:
1215 if (copied && likely(!tp->repair)) 1215 if (copied)
1216 tcp_push(sk, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH); 1216 tcp_push(sk, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH);
1217 1217
1218 if ((err = sk_stream_wait_memory(sk, &timeo)) != 0) 1218 if ((err = sk_stream_wait_memory(sk, &timeo)) != 0)
@@ -1223,7 +1223,7 @@ wait_for_memory:
1223 } 1223 }
1224 1224
1225out: 1225out:
1226 if (copied && likely(!tp->repair)) 1226 if (copied)
1227 tcp_push(sk, flags, mss_now, tp->nonagle); 1227 tcp_push(sk, flags, mss_now, tp->nonagle);
1228 release_sock(sk); 1228 release_sock(sk);
1229 return copied + copied_syn; 1229 return copied + copied_syn;
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 2c2b13a999ea..609ff98aeb47 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -5313,11 +5313,6 @@ static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb,
5313 goto discard; 5313 goto discard;
5314 } 5314 }
5315 5315
5316 /* ts_recent update must be made after we are sure that the packet
5317 * is in window.
5318 */
5319 tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq);
5320
5321 /* step 3: check security and precedence [ignored] */ 5316 /* step 3: check security and precedence [ignored] */
5322 5317
5323 /* step 4: Check for a SYN 5318 /* step 4: Check for a SYN
@@ -5552,6 +5547,11 @@ step5:
5552 if (th->ack && tcp_ack(sk, skb, FLAG_SLOWPATH) < 0) 5547 if (th->ack && tcp_ack(sk, skb, FLAG_SLOWPATH) < 0)
5553 goto discard; 5548 goto discard;
5554 5549
5550 /* ts_recent update must be made after we are sure that the packet
5551 * is in window.
5552 */
5553 tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq);
5554
5555 tcp_rcv_rtt_measure_ts(sk, skb); 5555 tcp_rcv_rtt_measure_ts(sk, skb);
5556 5556
5557 /* Process urgent data. */ 5557 /* Process urgent data. */
@@ -6130,6 +6130,11 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
6130 } else 6130 } else
6131 goto discard; 6131 goto discard;
6132 6132
6133 /* ts_recent update must be made after we are sure that the packet
6134 * is in window.
6135 */
6136 tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq);
6137
6133 /* step 6: check the URG bit */ 6138 /* step 6: check the URG bit */
6134 tcp_urg(sk, skb, th); 6139 tcp_urg(sk, skb, th);
6135 6140
diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c
index 53bc5847bfa8..f696d7c2e9fa 100644
--- a/net/ipv4/tcp_metrics.c
+++ b/net/ipv4/tcp_metrics.c
@@ -1,7 +1,6 @@
1#include <linux/rcupdate.h> 1#include <linux/rcupdate.h>
2#include <linux/spinlock.h> 2#include <linux/spinlock.h>
3#include <linux/jiffies.h> 3#include <linux/jiffies.h>
4#include <linux/bootmem.h>
5#include <linux/module.h> 4#include <linux/module.h>
6#include <linux/cache.h> 5#include <linux/cache.h>
7#include <linux/slab.h> 6#include <linux/slab.h>
@@ -9,6 +8,7 @@
9#include <linux/tcp.h> 8#include <linux/tcp.h>
10#include <linux/hash.h> 9#include <linux/hash.h>
11#include <linux/tcp_metrics.h> 10#include <linux/tcp_metrics.h>
11#include <linux/vmalloc.h>
12 12
13#include <net/inet_connection_sock.h> 13#include <net/inet_connection_sock.h>
14#include <net/net_namespace.h> 14#include <net/net_namespace.h>
@@ -1034,7 +1034,10 @@ static int __net_init tcp_net_metrics_init(struct net *net)
1034 net->ipv4.tcp_metrics_hash_log = order_base_2(slots); 1034 net->ipv4.tcp_metrics_hash_log = order_base_2(slots);
1035 size = sizeof(struct tcpm_hash_bucket) << net->ipv4.tcp_metrics_hash_log; 1035 size = sizeof(struct tcpm_hash_bucket) << net->ipv4.tcp_metrics_hash_log;
1036 1036
1037 net->ipv4.tcp_metrics_hash = kzalloc(size, GFP_KERNEL); 1037 net->ipv4.tcp_metrics_hash = kzalloc(size, GFP_KERNEL | __GFP_NOWARN);
1038 if (!net->ipv4.tcp_metrics_hash)
1039 net->ipv4.tcp_metrics_hash = vzalloc(size);
1040
1038 if (!net->ipv4.tcp_metrics_hash) 1041 if (!net->ipv4.tcp_metrics_hash)
1039 return -ENOMEM; 1042 return -ENOMEM;
1040 1043
@@ -1055,7 +1058,10 @@ static void __net_exit tcp_net_metrics_exit(struct net *net)
1055 tm = next; 1058 tm = next;
1056 } 1059 }
1057 } 1060 }
1058 kfree(net->ipv4.tcp_metrics_hash); 1061 if (is_vmalloc_addr(net->ipv4.tcp_metrics_hash))
1062 vfree(net->ipv4.tcp_metrics_hash);
1063 else
1064 kfree(net->ipv4.tcp_metrics_hash);
1059} 1065}
1060 1066
1061static __net_initdata struct pernet_operations tcp_net_metrics_ops = { 1067static __net_initdata struct pernet_operations tcp_net_metrics_ops = {
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index cfe6ffe1c177..2798706cb063 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -1986,6 +1986,9 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
1986 tso_segs = tcp_init_tso_segs(sk, skb, mss_now); 1986 tso_segs = tcp_init_tso_segs(sk, skb, mss_now);
1987 BUG_ON(!tso_segs); 1987 BUG_ON(!tso_segs);
1988 1988
1989 if (unlikely(tp->repair) && tp->repair_queue == TCP_SEND_QUEUE)
1990 goto repair; /* Skip network transmission */
1991
1989 cwnd_quota = tcp_cwnd_test(tp, skb); 1992 cwnd_quota = tcp_cwnd_test(tp, skb);
1990 if (!cwnd_quota) 1993 if (!cwnd_quota)
1991 break; 1994 break;
@@ -2026,6 +2029,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
2026 if (unlikely(tcp_transmit_skb(sk, skb, 1, gfp))) 2029 if (unlikely(tcp_transmit_skb(sk, skb, 1, gfp)))
2027 break; 2030 break;
2028 2031
2032repair:
2029 /* Advance the send_head. This one is sent out. 2033 /* Advance the send_head. This one is sent out.
2030 * This call will increment packets_out. 2034 * This call will increment packets_out.
2031 */ 2035 */