diff options
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/fib_trie.c | 2 | ||||
-rw-r--r-- | net/ipv4/inet_connection_sock.c | 7 | ||||
-rw-r--r-- | net/ipv4/ip_output.c | 10 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_nat_sip.c | 9 | ||||
-rw-r--r-- | net/ipv4/route.c | 5 | ||||
-rw-r--r-- | net/ipv4/tcp.c | 4 | ||||
-rw-r--r-- | net/ipv4/tcp_cong.c | 3 | ||||
-rw-r--r-- | net/ipv4/tcp_input.c | 4 | ||||
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 23 | ||||
-rw-r--r-- | net/ipv4/tcp_metrics.c | 12 | ||||
-rw-r--r-- | net/ipv4/tcp_minisocks.c | 2 | ||||
-rw-r--r-- | net/ipv4/tcp_output.c | 37 | ||||
-rw-r--r-- | net/ipv4/tcp_timer.c | 6 | ||||
-rw-r--r-- | net/ipv4/udp.c | 2 |
14 files changed, 81 insertions, 45 deletions
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index f0cdb30921c0..57bd978483e1 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -367,7 +367,7 @@ static void __leaf_free_rcu(struct rcu_head *head) | |||
367 | 367 | ||
368 | static inline void free_leaf(struct leaf *l) | 368 | static inline void free_leaf(struct leaf *l) |
369 | { | 369 | { |
370 | call_rcu_bh(&l->rcu, __leaf_free_rcu); | 370 | call_rcu(&l->rcu, __leaf_free_rcu); |
371 | } | 371 | } |
372 | 372 | ||
373 | static inline void free_leaf_info(struct leaf_info *leaf) | 373 | static inline void free_leaf_info(struct leaf_info *leaf) |
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index db0cf17c00f7..7f75f21d7b83 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c | |||
@@ -404,12 +404,15 @@ struct dst_entry *inet_csk_route_child_sock(struct sock *sk, | |||
404 | { | 404 | { |
405 | const struct inet_request_sock *ireq = inet_rsk(req); | 405 | const struct inet_request_sock *ireq = inet_rsk(req); |
406 | struct inet_sock *newinet = inet_sk(newsk); | 406 | struct inet_sock *newinet = inet_sk(newsk); |
407 | struct ip_options_rcu *opt = ireq->opt; | 407 | struct ip_options_rcu *opt; |
408 | struct net *net = sock_net(sk); | 408 | struct net *net = sock_net(sk); |
409 | struct flowi4 *fl4; | 409 | struct flowi4 *fl4; |
410 | struct rtable *rt; | 410 | struct rtable *rt; |
411 | 411 | ||
412 | fl4 = &newinet->cork.fl.u.ip4; | 412 | fl4 = &newinet->cork.fl.u.ip4; |
413 | |||
414 | rcu_read_lock(); | ||
415 | opt = rcu_dereference(newinet->inet_opt); | ||
413 | flowi4_init_output(fl4, sk->sk_bound_dev_if, sk->sk_mark, | 416 | flowi4_init_output(fl4, sk->sk_bound_dev_if, sk->sk_mark, |
414 | RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE, | 417 | RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE, |
415 | sk->sk_protocol, inet_sk_flowi_flags(sk), | 418 | sk->sk_protocol, inet_sk_flowi_flags(sk), |
@@ -421,11 +424,13 @@ struct dst_entry *inet_csk_route_child_sock(struct sock *sk, | |||
421 | goto no_route; | 424 | goto no_route; |
422 | if (opt && opt->opt.is_strictroute && rt->rt_gateway) | 425 | if (opt && opt->opt.is_strictroute && rt->rt_gateway) |
423 | goto route_err; | 426 | goto route_err; |
427 | rcu_read_unlock(); | ||
424 | return &rt->dst; | 428 | return &rt->dst; |
425 | 429 | ||
426 | route_err: | 430 | route_err: |
427 | ip_rt_put(rt); | 431 | ip_rt_put(rt); |
428 | no_route: | 432 | no_route: |
433 | rcu_read_unlock(); | ||
429 | IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES); | 434 | IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES); |
430 | return NULL; | 435 | return NULL; |
431 | } | 436 | } |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index ba39a52d18c1..c196d749daf2 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -197,7 +197,7 @@ static inline int ip_finish_output2(struct sk_buff *skb) | |||
197 | neigh = __ipv4_neigh_lookup_noref(dev, nexthop); | 197 | neigh = __ipv4_neigh_lookup_noref(dev, nexthop); |
198 | if (unlikely(!neigh)) | 198 | if (unlikely(!neigh)) |
199 | neigh = __neigh_create(&arp_tbl, &nexthop, dev, false); | 199 | neigh = __neigh_create(&arp_tbl, &nexthop, dev, false); |
200 | if (neigh) { | 200 | if (!IS_ERR(neigh)) { |
201 | int res = dst_neigh_output(dst, neigh, skb); | 201 | int res = dst_neigh_output(dst, neigh, skb); |
202 | 202 | ||
203 | rcu_read_unlock_bh(); | 203 | rcu_read_unlock_bh(); |
@@ -1338,10 +1338,10 @@ struct sk_buff *__ip_make_skb(struct sock *sk, | |||
1338 | iph->ihl = 5; | 1338 | iph->ihl = 5; |
1339 | iph->tos = inet->tos; | 1339 | iph->tos = inet->tos; |
1340 | iph->frag_off = df; | 1340 | iph->frag_off = df; |
1341 | ip_select_ident(iph, &rt->dst, sk); | ||
1342 | iph->ttl = ttl; | 1341 | iph->ttl = ttl; |
1343 | iph->protocol = sk->sk_protocol; | 1342 | iph->protocol = sk->sk_protocol; |
1344 | ip_copy_addrs(iph, fl4); | 1343 | ip_copy_addrs(iph, fl4); |
1344 | ip_select_ident(iph, &rt->dst, sk); | ||
1345 | 1345 | ||
1346 | if (opt) { | 1346 | if (opt) { |
1347 | iph->ihl += opt->optlen>>2; | 1347 | iph->ihl += opt->optlen>>2; |
@@ -1366,9 +1366,8 @@ out: | |||
1366 | return skb; | 1366 | return skb; |
1367 | } | 1367 | } |
1368 | 1368 | ||
1369 | int ip_send_skb(struct sk_buff *skb) | 1369 | int ip_send_skb(struct net *net, struct sk_buff *skb) |
1370 | { | 1370 | { |
1371 | struct net *net = sock_net(skb->sk); | ||
1372 | int err; | 1371 | int err; |
1373 | 1372 | ||
1374 | err = ip_local_out(skb); | 1373 | err = ip_local_out(skb); |
@@ -1391,7 +1390,7 @@ int ip_push_pending_frames(struct sock *sk, struct flowi4 *fl4) | |||
1391 | return 0; | 1390 | return 0; |
1392 | 1391 | ||
1393 | /* Netfilter gets whole the not fragmented skb. */ | 1392 | /* Netfilter gets whole the not fragmented skb. */ |
1394 | return ip_send_skb(skb); | 1393 | return ip_send_skb(sock_net(sk), skb); |
1395 | } | 1394 | } |
1396 | 1395 | ||
1397 | /* | 1396 | /* |
@@ -1536,6 +1535,7 @@ void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, __be32 daddr, | |||
1536 | arg->csumoffset) = csum_fold(csum_add(nskb->csum, | 1535 | arg->csumoffset) = csum_fold(csum_add(nskb->csum, |
1537 | arg->csum)); | 1536 | arg->csum)); |
1538 | nskb->ip_summed = CHECKSUM_NONE; | 1537 | nskb->ip_summed = CHECKSUM_NONE; |
1538 | skb_orphan(nskb); | ||
1539 | skb_set_queue_mapping(nskb, skb_get_queue_mapping(skb)); | 1539 | skb_set_queue_mapping(nskb, skb_get_queue_mapping(skb)); |
1540 | ip_push_pending_frames(sk, &fl4); | 1540 | ip_push_pending_frames(sk, &fl4); |
1541 | } | 1541 | } |
diff --git a/net/ipv4/netfilter/nf_nat_sip.c b/net/ipv4/netfilter/nf_nat_sip.c index ea4a23813d26..4ad9cf173992 100644 --- a/net/ipv4/netfilter/nf_nat_sip.c +++ b/net/ipv4/netfilter/nf_nat_sip.c | |||
@@ -148,7 +148,7 @@ static unsigned int ip_nat_sip(struct sk_buff *skb, unsigned int dataoff, | |||
148 | if (ct_sip_parse_header_uri(ct, *dptr, NULL, *datalen, | 148 | if (ct_sip_parse_header_uri(ct, *dptr, NULL, *datalen, |
149 | hdr, NULL, &matchoff, &matchlen, | 149 | hdr, NULL, &matchoff, &matchlen, |
150 | &addr, &port) > 0) { | 150 | &addr, &port) > 0) { |
151 | unsigned int matchend, poff, plen, buflen, n; | 151 | unsigned int olen, matchend, poff, plen, buflen, n; |
152 | char buffer[sizeof("nnn.nnn.nnn.nnn:nnnnn")]; | 152 | char buffer[sizeof("nnn.nnn.nnn.nnn:nnnnn")]; |
153 | 153 | ||
154 | /* We're only interested in headers related to this | 154 | /* We're only interested in headers related to this |
@@ -163,17 +163,18 @@ static unsigned int ip_nat_sip(struct sk_buff *skb, unsigned int dataoff, | |||
163 | goto next; | 163 | goto next; |
164 | } | 164 | } |
165 | 165 | ||
166 | olen = *datalen; | ||
166 | if (!map_addr(skb, dataoff, dptr, datalen, matchoff, matchlen, | 167 | if (!map_addr(skb, dataoff, dptr, datalen, matchoff, matchlen, |
167 | &addr, port)) | 168 | &addr, port)) |
168 | return NF_DROP; | 169 | return NF_DROP; |
169 | 170 | ||
170 | matchend = matchoff + matchlen; | 171 | matchend = matchoff + matchlen + *datalen - olen; |
171 | 172 | ||
172 | /* The maddr= parameter (RFC 2361) specifies where to send | 173 | /* The maddr= parameter (RFC 2361) specifies where to send |
173 | * the reply. */ | 174 | * the reply. */ |
174 | if (ct_sip_parse_address_param(ct, *dptr, matchend, *datalen, | 175 | if (ct_sip_parse_address_param(ct, *dptr, matchend, *datalen, |
175 | "maddr=", &poff, &plen, | 176 | "maddr=", &poff, &plen, |
176 | &addr) > 0 && | 177 | &addr, true) > 0 && |
177 | addr.ip == ct->tuplehash[dir].tuple.src.u3.ip && | 178 | addr.ip == ct->tuplehash[dir].tuple.src.u3.ip && |
178 | addr.ip != ct->tuplehash[!dir].tuple.dst.u3.ip) { | 179 | addr.ip != ct->tuplehash[!dir].tuple.dst.u3.ip) { |
179 | buflen = sprintf(buffer, "%pI4", | 180 | buflen = sprintf(buffer, "%pI4", |
@@ -187,7 +188,7 @@ static unsigned int ip_nat_sip(struct sk_buff *skb, unsigned int dataoff, | |||
187 | * from which the server received the request. */ | 188 | * from which the server received the request. */ |
188 | if (ct_sip_parse_address_param(ct, *dptr, matchend, *datalen, | 189 | if (ct_sip_parse_address_param(ct, *dptr, matchend, *datalen, |
189 | "received=", &poff, &plen, | 190 | "received=", &poff, &plen, |
190 | &addr) > 0 && | 191 | &addr, false) > 0 && |
191 | addr.ip == ct->tuplehash[dir].tuple.dst.u3.ip && | 192 | addr.ip == ct->tuplehash[dir].tuple.dst.u3.ip && |
192 | addr.ip != ct->tuplehash[!dir].tuple.src.u3.ip) { | 193 | addr.ip != ct->tuplehash[!dir].tuple.src.u3.ip) { |
193 | buflen = sprintf(buffer, "%pI4", | 194 | buflen = sprintf(buffer, "%pI4", |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index c035251beb07..fd9ecb52c66b 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -70,7 +70,6 @@ | |||
70 | #include <linux/types.h> | 70 | #include <linux/types.h> |
71 | #include <linux/kernel.h> | 71 | #include <linux/kernel.h> |
72 | #include <linux/mm.h> | 72 | #include <linux/mm.h> |
73 | #include <linux/bootmem.h> | ||
74 | #include <linux/string.h> | 73 | #include <linux/string.h> |
75 | #include <linux/socket.h> | 74 | #include <linux/socket.h> |
76 | #include <linux/sockios.h> | 75 | #include <linux/sockios.h> |
@@ -80,7 +79,6 @@ | |||
80 | #include <linux/netdevice.h> | 79 | #include <linux/netdevice.h> |
81 | #include <linux/proc_fs.h> | 80 | #include <linux/proc_fs.h> |
82 | #include <linux/init.h> | 81 | #include <linux/init.h> |
83 | #include <linux/workqueue.h> | ||
84 | #include <linux/skbuff.h> | 82 | #include <linux/skbuff.h> |
85 | #include <linux/inetdevice.h> | 83 | #include <linux/inetdevice.h> |
86 | #include <linux/igmp.h> | 84 | #include <linux/igmp.h> |
@@ -88,11 +86,9 @@ | |||
88 | #include <linux/mroute.h> | 86 | #include <linux/mroute.h> |
89 | #include <linux/netfilter_ipv4.h> | 87 | #include <linux/netfilter_ipv4.h> |
90 | #include <linux/random.h> | 88 | #include <linux/random.h> |
91 | #include <linux/jhash.h> | ||
92 | #include <linux/rcupdate.h> | 89 | #include <linux/rcupdate.h> |
93 | #include <linux/times.h> | 90 | #include <linux/times.h> |
94 | #include <linux/slab.h> | 91 | #include <linux/slab.h> |
95 | #include <linux/prefetch.h> | ||
96 | #include <net/dst.h> | 92 | #include <net/dst.h> |
97 | #include <net/net_namespace.h> | 93 | #include <net/net_namespace.h> |
98 | #include <net/protocol.h> | 94 | #include <net/protocol.h> |
@@ -2032,7 +2028,6 @@ struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *fl4) | |||
2032 | } | 2028 | } |
2033 | dev_out = net->loopback_dev; | 2029 | dev_out = net->loopback_dev; |
2034 | fl4->flowi4_oif = dev_out->ifindex; | 2030 | fl4->flowi4_oif = dev_out->ifindex; |
2035 | res.fi = NULL; | ||
2036 | flags |= RTCF_LOCAL; | 2031 | flags |= RTCF_LOCAL; |
2037 | goto make_route; | 2032 | goto make_route; |
2038 | } | 2033 | } |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index e7e6eeae49c0..2109ff4a1daf 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -811,7 +811,9 @@ static unsigned int tcp_xmit_size_goal(struct sock *sk, u32 mss_now, | |||
811 | old_size_goal + mss_now > xmit_size_goal)) { | 811 | old_size_goal + mss_now > xmit_size_goal)) { |
812 | xmit_size_goal = old_size_goal; | 812 | xmit_size_goal = old_size_goal; |
813 | } else { | 813 | } else { |
814 | tp->xmit_size_goal_segs = xmit_size_goal / mss_now; | 814 | tp->xmit_size_goal_segs = |
815 | min_t(u16, xmit_size_goal / mss_now, | ||
816 | sk->sk_gso_max_segs); | ||
815 | xmit_size_goal = tp->xmit_size_goal_segs * mss_now; | 817 | xmit_size_goal = tp->xmit_size_goal_segs * mss_now; |
816 | } | 818 | } |
817 | } | 819 | } |
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c index 4d4db16e336e..1432cdb0644c 100644 --- a/net/ipv4/tcp_cong.c +++ b/net/ipv4/tcp_cong.c | |||
@@ -291,7 +291,8 @@ bool tcp_is_cwnd_limited(const struct sock *sk, u32 in_flight) | |||
291 | left = tp->snd_cwnd - in_flight; | 291 | left = tp->snd_cwnd - in_flight; |
292 | if (sk_can_gso(sk) && | 292 | if (sk_can_gso(sk) && |
293 | left * sysctl_tcp_tso_win_divisor < tp->snd_cwnd && | 293 | left * sysctl_tcp_tso_win_divisor < tp->snd_cwnd && |
294 | left * tp->mss_cache < sk->sk_gso_max_size) | 294 | left * tp->mss_cache < sk->sk_gso_max_size && |
295 | left < sk->sk_gso_max_segs) | ||
295 | return true; | 296 | return true; |
296 | return left <= tcp_max_tso_deferred_mss(tp); | 297 | return left <= tcp_max_tso_deferred_mss(tp); |
297 | } | 298 | } |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 2fd2bc9e3c64..85308b90df80 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -5392,6 +5392,8 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, | |||
5392 | { | 5392 | { |
5393 | struct tcp_sock *tp = tcp_sk(sk); | 5393 | struct tcp_sock *tp = tcp_sk(sk); |
5394 | 5394 | ||
5395 | if (unlikely(sk->sk_rx_dst == NULL)) | ||
5396 | inet_csk(sk)->icsk_af_ops->sk_rx_dst_set(sk, skb); | ||
5395 | /* | 5397 | /* |
5396 | * Header prediction. | 5398 | * Header prediction. |
5397 | * The code loosely follows the one in the famous | 5399 | * The code loosely follows the one in the famous |
@@ -5605,7 +5607,7 @@ void tcp_finish_connect(struct sock *sk, struct sk_buff *skb) | |||
5605 | tcp_set_state(sk, TCP_ESTABLISHED); | 5607 | tcp_set_state(sk, TCP_ESTABLISHED); |
5606 | 5608 | ||
5607 | if (skb != NULL) { | 5609 | if (skb != NULL) { |
5608 | inet_sk_rx_dst_set(sk, skb); | 5610 | icsk->icsk_af_ops->sk_rx_dst_set(sk, skb); |
5609 | security_inet_conn_established(sk, skb); | 5611 | security_inet_conn_established(sk, skb); |
5610 | } | 5612 | } |
5611 | 5613 | ||
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 42b2a6a73092..00a748d14062 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -417,10 +417,12 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) | |||
417 | 417 | ||
418 | if (code == ICMP_FRAG_NEEDED) { /* PMTU discovery (RFC1191) */ | 418 | if (code == ICMP_FRAG_NEEDED) { /* PMTU discovery (RFC1191) */ |
419 | tp->mtu_info = info; | 419 | tp->mtu_info = info; |
420 | if (!sock_owned_by_user(sk)) | 420 | if (!sock_owned_by_user(sk)) { |
421 | tcp_v4_mtu_reduced(sk); | 421 | tcp_v4_mtu_reduced(sk); |
422 | else | 422 | } else { |
423 | set_bit(TCP_MTU_REDUCED_DEFERRED, &tp->tsq_flags); | 423 | if (!test_and_set_bit(TCP_MTU_REDUCED_DEFERRED, &tp->tsq_flags)) |
424 | sock_hold(sk); | ||
425 | } | ||
424 | goto out; | 426 | goto out; |
425 | } | 427 | } |
426 | 428 | ||
@@ -1462,6 +1464,7 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1462 | goto exit_nonewsk; | 1464 | goto exit_nonewsk; |
1463 | 1465 | ||
1464 | newsk->sk_gso_type = SKB_GSO_TCPV4; | 1466 | newsk->sk_gso_type = SKB_GSO_TCPV4; |
1467 | inet_sk_rx_dst_set(newsk, skb); | ||
1465 | 1468 | ||
1466 | newtp = tcp_sk(newsk); | 1469 | newtp = tcp_sk(newsk); |
1467 | newinet = inet_sk(newsk); | 1470 | newinet = inet_sk(newsk); |
@@ -1627,9 +1630,6 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb) | |||
1627 | sk->sk_rx_dst = NULL; | 1630 | sk->sk_rx_dst = NULL; |
1628 | } | 1631 | } |
1629 | } | 1632 | } |
1630 | if (unlikely(sk->sk_rx_dst == NULL)) | ||
1631 | inet_sk_rx_dst_set(sk, skb); | ||
1632 | |||
1633 | if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len)) { | 1633 | if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len)) { |
1634 | rsk = sk; | 1634 | rsk = sk; |
1635 | goto reset; | 1635 | goto reset; |
@@ -1872,10 +1872,21 @@ static struct timewait_sock_ops tcp_timewait_sock_ops = { | |||
1872 | .twsk_destructor= tcp_twsk_destructor, | 1872 | .twsk_destructor= tcp_twsk_destructor, |
1873 | }; | 1873 | }; |
1874 | 1874 | ||
1875 | void inet_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb) | ||
1876 | { | ||
1877 | struct dst_entry *dst = skb_dst(skb); | ||
1878 | |||
1879 | dst_hold(dst); | ||
1880 | sk->sk_rx_dst = dst; | ||
1881 | inet_sk(sk)->rx_dst_ifindex = skb->skb_iif; | ||
1882 | } | ||
1883 | EXPORT_SYMBOL(inet_sk_rx_dst_set); | ||
1884 | |||
1875 | const struct inet_connection_sock_af_ops ipv4_specific = { | 1885 | const struct inet_connection_sock_af_ops ipv4_specific = { |
1876 | .queue_xmit = ip_queue_xmit, | 1886 | .queue_xmit = ip_queue_xmit, |
1877 | .send_check = tcp_v4_send_check, | 1887 | .send_check = tcp_v4_send_check, |
1878 | .rebuild_header = inet_sk_rebuild_header, | 1888 | .rebuild_header = inet_sk_rebuild_header, |
1889 | .sk_rx_dst_set = inet_sk_rx_dst_set, | ||
1879 | .conn_request = tcp_v4_conn_request, | 1890 | .conn_request = tcp_v4_conn_request, |
1880 | .syn_recv_sock = tcp_v4_syn_recv_sock, | 1891 | .syn_recv_sock = tcp_v4_syn_recv_sock, |
1881 | .net_header_len = sizeof(struct iphdr), | 1892 | .net_header_len = sizeof(struct iphdr), |
diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c index 2288a6399e1e..0abe67bb4d3a 100644 --- a/net/ipv4/tcp_metrics.c +++ b/net/ipv4/tcp_metrics.c | |||
@@ -731,6 +731,18 @@ static int __net_init tcp_net_metrics_init(struct net *net) | |||
731 | 731 | ||
732 | static void __net_exit tcp_net_metrics_exit(struct net *net) | 732 | static void __net_exit tcp_net_metrics_exit(struct net *net) |
733 | { | 733 | { |
734 | unsigned int i; | ||
735 | |||
736 | for (i = 0; i < (1U << net->ipv4.tcp_metrics_hash_log) ; i++) { | ||
737 | struct tcp_metrics_block *tm, *next; | ||
738 | |||
739 | tm = rcu_dereference_protected(net->ipv4.tcp_metrics_hash[i].chain, 1); | ||
740 | while (tm) { | ||
741 | next = rcu_dereference_protected(tm->tcpm_next, 1); | ||
742 | kfree(tm); | ||
743 | tm = next; | ||
744 | } | ||
745 | } | ||
734 | kfree(net->ipv4.tcp_metrics_hash); | 746 | kfree(net->ipv4.tcp_metrics_hash); |
735 | } | 747 | } |
736 | 748 | ||
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 232a90c3ec86..6ff7f10dce9d 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c | |||
@@ -387,8 +387,6 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, | |||
387 | struct tcp_sock *oldtp = tcp_sk(sk); | 387 | struct tcp_sock *oldtp = tcp_sk(sk); |
388 | struct tcp_cookie_values *oldcvp = oldtp->cookie_values; | 388 | struct tcp_cookie_values *oldcvp = oldtp->cookie_values; |
389 | 389 | ||
390 | inet_sk_rx_dst_set(newsk, skb); | ||
391 | |||
392 | /* TCP Cookie Transactions require space for the cookie pair, | 390 | /* TCP Cookie Transactions require space for the cookie pair, |
393 | * as it differs for each connection. There is no need to | 391 | * as it differs for each connection. There is no need to |
394 | * copy any s_data_payload stored at the original socket. | 392 | * copy any s_data_payload stored at the original socket. |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 3f1bcff0b10b..d04632673a9e 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -910,14 +910,18 @@ void tcp_release_cb(struct sock *sk) | |||
910 | if (flags & (1UL << TCP_TSQ_DEFERRED)) | 910 | if (flags & (1UL << TCP_TSQ_DEFERRED)) |
911 | tcp_tsq_handler(sk); | 911 | tcp_tsq_handler(sk); |
912 | 912 | ||
913 | if (flags & (1UL << TCP_WRITE_TIMER_DEFERRED)) | 913 | if (flags & (1UL << TCP_WRITE_TIMER_DEFERRED)) { |
914 | tcp_write_timer_handler(sk); | 914 | tcp_write_timer_handler(sk); |
915 | 915 | __sock_put(sk); | |
916 | if (flags & (1UL << TCP_DELACK_TIMER_DEFERRED)) | 916 | } |
917 | if (flags & (1UL << TCP_DELACK_TIMER_DEFERRED)) { | ||
917 | tcp_delack_timer_handler(sk); | 918 | tcp_delack_timer_handler(sk); |
918 | 919 | __sock_put(sk); | |
919 | if (flags & (1UL << TCP_MTU_REDUCED_DEFERRED)) | 920 | } |
921 | if (flags & (1UL << TCP_MTU_REDUCED_DEFERRED)) { | ||
920 | sk->sk_prot->mtu_reduced(sk); | 922 | sk->sk_prot->mtu_reduced(sk); |
923 | __sock_put(sk); | ||
924 | } | ||
921 | } | 925 | } |
922 | EXPORT_SYMBOL(tcp_release_cb); | 926 | EXPORT_SYMBOL(tcp_release_cb); |
923 | 927 | ||
@@ -940,7 +944,7 @@ void __init tcp_tasklet_init(void) | |||
940 | * We cant xmit new skbs from this context, as we might already | 944 | * We cant xmit new skbs from this context, as we might already |
941 | * hold qdisc lock. | 945 | * hold qdisc lock. |
942 | */ | 946 | */ |
943 | void tcp_wfree(struct sk_buff *skb) | 947 | static void tcp_wfree(struct sk_buff *skb) |
944 | { | 948 | { |
945 | struct sock *sk = skb->sk; | 949 | struct sock *sk = skb->sk; |
946 | struct tcp_sock *tp = tcp_sk(sk); | 950 | struct tcp_sock *tp = tcp_sk(sk); |
@@ -1522,21 +1526,21 @@ static void tcp_cwnd_validate(struct sock *sk) | |||
1522 | * when we would be allowed to send the split-due-to-Nagle skb fully. | 1526 | * when we would be allowed to send the split-due-to-Nagle skb fully. |
1523 | */ | 1527 | */ |
1524 | static unsigned int tcp_mss_split_point(const struct sock *sk, const struct sk_buff *skb, | 1528 | static unsigned int tcp_mss_split_point(const struct sock *sk, const struct sk_buff *skb, |
1525 | unsigned int mss_now, unsigned int cwnd) | 1529 | unsigned int mss_now, unsigned int max_segs) |
1526 | { | 1530 | { |
1527 | const struct tcp_sock *tp = tcp_sk(sk); | 1531 | const struct tcp_sock *tp = tcp_sk(sk); |
1528 | u32 needed, window, cwnd_len; | 1532 | u32 needed, window, max_len; |
1529 | 1533 | ||
1530 | window = tcp_wnd_end(tp) - TCP_SKB_CB(skb)->seq; | 1534 | window = tcp_wnd_end(tp) - TCP_SKB_CB(skb)->seq; |
1531 | cwnd_len = mss_now * cwnd; | 1535 | max_len = mss_now * max_segs; |
1532 | 1536 | ||
1533 | if (likely(cwnd_len <= window && skb != tcp_write_queue_tail(sk))) | 1537 | if (likely(max_len <= window && skb != tcp_write_queue_tail(sk))) |
1534 | return cwnd_len; | 1538 | return max_len; |
1535 | 1539 | ||
1536 | needed = min(skb->len, window); | 1540 | needed = min(skb->len, window); |
1537 | 1541 | ||
1538 | if (cwnd_len <= needed) | 1542 | if (max_len <= needed) |
1539 | return cwnd_len; | 1543 | return max_len; |
1540 | 1544 | ||
1541 | return needed - needed % mss_now; | 1545 | return needed - needed % mss_now; |
1542 | } | 1546 | } |
@@ -1765,7 +1769,8 @@ static bool tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb) | |||
1765 | limit = min(send_win, cong_win); | 1769 | limit = min(send_win, cong_win); |
1766 | 1770 | ||
1767 | /* If a full-sized TSO skb can be sent, do it. */ | 1771 | /* If a full-sized TSO skb can be sent, do it. */ |
1768 | if (limit >= sk->sk_gso_max_size) | 1772 | if (limit >= min_t(unsigned int, sk->sk_gso_max_size, |
1773 | sk->sk_gso_max_segs * tp->mss_cache)) | ||
1769 | goto send_now; | 1774 | goto send_now; |
1770 | 1775 | ||
1771 | /* Middle in queue won't get any more data, full sendable already? */ | 1776 | /* Middle in queue won't get any more data, full sendable already? */ |
@@ -1999,7 +2004,9 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, | |||
1999 | limit = mss_now; | 2004 | limit = mss_now; |
2000 | if (tso_segs > 1 && !tcp_urg_mode(tp)) | 2005 | if (tso_segs > 1 && !tcp_urg_mode(tp)) |
2001 | limit = tcp_mss_split_point(sk, skb, mss_now, | 2006 | limit = tcp_mss_split_point(sk, skb, mss_now, |
2002 | cwnd_quota); | 2007 | min_t(unsigned int, |
2008 | cwnd_quota, | ||
2009 | sk->sk_gso_max_segs)); | ||
2003 | 2010 | ||
2004 | if (skb->len > limit && | 2011 | if (skb->len > limit && |
2005 | unlikely(tso_fragment(sk, skb, limit, mss_now, gfp))) | 2012 | unlikely(tso_fragment(sk, skb, limit, mss_now, gfp))) |
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 6df36ad55a38..b774a03bd1dc 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c | |||
@@ -252,7 +252,8 @@ static void tcp_delack_timer(unsigned long data) | |||
252 | inet_csk(sk)->icsk_ack.blocked = 1; | 252 | inet_csk(sk)->icsk_ack.blocked = 1; |
253 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_DELAYEDACKLOCKED); | 253 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_DELAYEDACKLOCKED); |
254 | /* deleguate our work to tcp_release_cb() */ | 254 | /* deleguate our work to tcp_release_cb() */ |
255 | set_bit(TCP_WRITE_TIMER_DEFERRED, &tcp_sk(sk)->tsq_flags); | 255 | if (!test_and_set_bit(TCP_DELACK_TIMER_DEFERRED, &tcp_sk(sk)->tsq_flags)) |
256 | sock_hold(sk); | ||
256 | } | 257 | } |
257 | bh_unlock_sock(sk); | 258 | bh_unlock_sock(sk); |
258 | sock_put(sk); | 259 | sock_put(sk); |
@@ -481,7 +482,8 @@ static void tcp_write_timer(unsigned long data) | |||
481 | tcp_write_timer_handler(sk); | 482 | tcp_write_timer_handler(sk); |
482 | } else { | 483 | } else { |
483 | /* deleguate our work to tcp_release_cb() */ | 484 | /* deleguate our work to tcp_release_cb() */ |
484 | set_bit(TCP_WRITE_TIMER_DEFERRED, &tcp_sk(sk)->tsq_flags); | 485 | if (!test_and_set_bit(TCP_WRITE_TIMER_DEFERRED, &tcp_sk(sk)->tsq_flags)) |
486 | sock_hold(sk); | ||
485 | } | 487 | } |
486 | bh_unlock_sock(sk); | 488 | bh_unlock_sock(sk); |
487 | sock_put(sk); | 489 | sock_put(sk); |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index b4c3582a991f..6f6d1aca3c3d 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -758,7 +758,7 @@ static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4) | |||
758 | uh->check = CSUM_MANGLED_0; | 758 | uh->check = CSUM_MANGLED_0; |
759 | 759 | ||
760 | send: | 760 | send: |
761 | err = ip_send_skb(skb); | 761 | err = ip_send_skb(sock_net(sk), skb); |
762 | if (err) { | 762 | if (err) { |
763 | if (err == -ENOBUFS && !inet->recverr) { | 763 | if (err == -ENOBUFS && !inet->recverr) { |
764 | UDP_INC_STATS_USER(sock_net(sk), | 764 | UDP_INC_STATS_USER(sock_net(sk), |