diff options
Diffstat (limited to 'net/ipv4/tcp_ipv4.c')
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 223 |
1 files changed, 88 insertions, 135 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index f1756ee02207..3571f2be4470 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -122,7 +122,7 @@ int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp) | |||
122 | and use initial timestamp retrieved from peer table. | 122 | and use initial timestamp retrieved from peer table. |
123 | */ | 123 | */ |
124 | if (tcptw->tw_ts_recent_stamp && | 124 | if (tcptw->tw_ts_recent_stamp && |
125 | (twp == NULL || (sysctl_tcp_tw_reuse && | 125 | (!twp || (sysctl_tcp_tw_reuse && |
126 | get_seconds() - tcptw->tw_ts_recent_stamp > 1))) { | 126 | get_seconds() - tcptw->tw_ts_recent_stamp > 1))) { |
127 | tp->write_seq = tcptw->tw_snd_nxt + 65535 + 2; | 127 | tp->write_seq = tcptw->tw_snd_nxt + 65535 + 2; |
128 | if (tp->write_seq == 0) | 128 | if (tp->write_seq == 0) |
@@ -189,7 +189,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
189 | 189 | ||
190 | if (!inet->inet_saddr) | 190 | if (!inet->inet_saddr) |
191 | inet->inet_saddr = fl4->saddr; | 191 | inet->inet_saddr = fl4->saddr; |
192 | inet->inet_rcv_saddr = inet->inet_saddr; | 192 | sk_rcv_saddr_set(sk, inet->inet_saddr); |
193 | 193 | ||
194 | if (tp->rx_opt.ts_recent_stamp && inet->inet_daddr != daddr) { | 194 | if (tp->rx_opt.ts_recent_stamp && inet->inet_daddr != daddr) { |
195 | /* Reset inherited state */ | 195 | /* Reset inherited state */ |
@@ -204,7 +204,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
204 | tcp_fetch_timewait_stamp(sk, &rt->dst); | 204 | tcp_fetch_timewait_stamp(sk, &rt->dst); |
205 | 205 | ||
206 | inet->inet_dport = usin->sin_port; | 206 | inet->inet_dport = usin->sin_port; |
207 | inet->inet_daddr = daddr; | 207 | sk_daddr_set(sk, daddr); |
208 | 208 | ||
209 | inet_csk(sk)->icsk_ext_hdr_len = 0; | 209 | inet_csk(sk)->icsk_ext_hdr_len = 0; |
210 | if (inet_opt) | 210 | if (inet_opt) |
@@ -310,6 +310,34 @@ static void do_redirect(struct sk_buff *skb, struct sock *sk) | |||
310 | dst->ops->redirect(dst, sk, skb); | 310 | dst->ops->redirect(dst, sk, skb); |
311 | } | 311 | } |
312 | 312 | ||
313 | |||
314 | /* handle ICMP messages on TCP_NEW_SYN_RECV request sockets */ | ||
315 | void tcp_req_err(struct sock *sk, u32 seq) | ||
316 | { | ||
317 | struct request_sock *req = inet_reqsk(sk); | ||
318 | struct net *net = sock_net(sk); | ||
319 | |||
320 | /* ICMPs are not backlogged, hence we cannot get | ||
321 | * an established socket here. | ||
322 | */ | ||
323 | WARN_ON(req->sk); | ||
324 | |||
325 | if (seq != tcp_rsk(req)->snt_isn) { | ||
326 | NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS); | ||
327 | reqsk_put(req); | ||
328 | } else { | ||
329 | /* | ||
330 | * Still in SYN_RECV, just remove it silently. | ||
331 | * There is no good way to pass the error to the newly | ||
332 | * created socket, and POSIX does not want network | ||
333 | * errors returned from accept(). | ||
334 | */ | ||
335 | NET_INC_STATS_BH(net, LINUX_MIB_LISTENDROPS); | ||
336 | inet_csk_reqsk_queue_drop(req->rsk_listener, req); | ||
337 | } | ||
338 | } | ||
339 | EXPORT_SYMBOL(tcp_req_err); | ||
340 | |||
313 | /* | 341 | /* |
314 | * This routine is called by the ICMP module when it gets some | 342 | * This routine is called by the ICMP module when it gets some |
315 | * sort of error condition. If err < 0 then the socket should | 343 | * sort of error condition. If err < 0 then the socket should |
@@ -343,8 +371,9 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) | |||
343 | int err; | 371 | int err; |
344 | struct net *net = dev_net(icmp_skb->dev); | 372 | struct net *net = dev_net(icmp_skb->dev); |
345 | 373 | ||
346 | sk = inet_lookup(net, &tcp_hashinfo, iph->daddr, th->dest, | 374 | sk = __inet_lookup_established(net, &tcp_hashinfo, iph->daddr, |
347 | iph->saddr, th->source, inet_iif(icmp_skb)); | 375 | th->dest, iph->saddr, ntohs(th->source), |
376 | inet_iif(icmp_skb)); | ||
348 | if (!sk) { | 377 | if (!sk) { |
349 | ICMP_INC_STATS_BH(net, ICMP_MIB_INERRORS); | 378 | ICMP_INC_STATS_BH(net, ICMP_MIB_INERRORS); |
350 | return; | 379 | return; |
@@ -353,6 +382,9 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) | |||
353 | inet_twsk_put(inet_twsk(sk)); | 382 | inet_twsk_put(inet_twsk(sk)); |
354 | return; | 383 | return; |
355 | } | 384 | } |
385 | seq = ntohl(th->seq); | ||
386 | if (sk->sk_state == TCP_NEW_SYN_RECV) | ||
387 | return tcp_req_err(sk, seq); | ||
356 | 388 | ||
357 | bh_lock_sock(sk); | 389 | bh_lock_sock(sk); |
358 | /* If too many ICMPs get dropped on busy | 390 | /* If too many ICMPs get dropped on busy |
@@ -374,7 +406,6 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) | |||
374 | 406 | ||
375 | icsk = inet_csk(sk); | 407 | icsk = inet_csk(sk); |
376 | tp = tcp_sk(sk); | 408 | tp = tcp_sk(sk); |
377 | seq = ntohl(th->seq); | ||
378 | /* XXX (TFO) - tp->snd_una should be ISN (tcp_create_openreq_child() */ | 409 | /* XXX (TFO) - tp->snd_una should be ISN (tcp_create_openreq_child() */ |
379 | fastopen = tp->fastopen_rsk; | 410 | fastopen = tp->fastopen_rsk; |
380 | snd_una = fastopen ? tcp_rsk(fastopen)->snt_isn : tp->snd_una; | 411 | snd_una = fastopen ? tcp_rsk(fastopen)->snt_isn : tp->snd_una; |
@@ -458,42 +489,12 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) | |||
458 | } | 489 | } |
459 | 490 | ||
460 | switch (sk->sk_state) { | 491 | switch (sk->sk_state) { |
461 | struct request_sock *req, **prev; | ||
462 | case TCP_LISTEN: | ||
463 | if (sock_owned_by_user(sk)) | ||
464 | goto out; | ||
465 | |||
466 | req = inet_csk_search_req(sk, &prev, th->dest, | ||
467 | iph->daddr, iph->saddr); | ||
468 | if (!req) | ||
469 | goto out; | ||
470 | |||
471 | /* ICMPs are not backlogged, hence we cannot get | ||
472 | an established socket here. | ||
473 | */ | ||
474 | WARN_ON(req->sk); | ||
475 | |||
476 | if (seq != tcp_rsk(req)->snt_isn) { | ||
477 | NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS); | ||
478 | goto out; | ||
479 | } | ||
480 | |||
481 | /* | ||
482 | * Still in SYN_RECV, just remove it silently. | ||
483 | * There is no good way to pass the error to the newly | ||
484 | * created socket, and POSIX does not want network | ||
485 | * errors returned from accept(). | ||
486 | */ | ||
487 | inet_csk_reqsk_queue_drop(sk, req, prev); | ||
488 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); | ||
489 | goto out; | ||
490 | |||
491 | case TCP_SYN_SENT: | 492 | case TCP_SYN_SENT: |
492 | case TCP_SYN_RECV: | 493 | case TCP_SYN_RECV: |
493 | /* Only in fast or simultaneous open. If a fast open socket is | 494 | /* Only in fast or simultaneous open. If a fast open socket is |
494 | * is already accepted it is treated as a connected one below. | 495 | * is already accepted it is treated as a connected one below. |
495 | */ | 496 | */ |
496 | if (fastopen && fastopen->sk == NULL) | 497 | if (fastopen && !fastopen->sk) |
497 | break; | 498 | break; |
498 | 499 | ||
499 | if (!sock_owned_by_user(sk)) { | 500 | if (!sock_owned_by_user(sk)) { |
@@ -647,7 +648,7 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb) | |||
647 | if (!key) | 648 | if (!key) |
648 | goto release_sk1; | 649 | goto release_sk1; |
649 | 650 | ||
650 | genhash = tcp_v4_md5_hash_skb(newhash, key, NULL, NULL, skb); | 651 | genhash = tcp_v4_md5_hash_skb(newhash, key, NULL, skb); |
651 | if (genhash || memcmp(hash_location, newhash, 16) != 0) | 652 | if (genhash || memcmp(hash_location, newhash, 16) != 0) |
652 | goto release_sk1; | 653 | goto release_sk1; |
653 | } else { | 654 | } else { |
@@ -855,35 +856,6 @@ static void tcp_v4_reqsk_destructor(struct request_sock *req) | |||
855 | kfree(inet_rsk(req)->opt); | 856 | kfree(inet_rsk(req)->opt); |
856 | } | 857 | } |
857 | 858 | ||
858 | /* | ||
859 | * Return true if a syncookie should be sent | ||
860 | */ | ||
861 | bool tcp_syn_flood_action(struct sock *sk, | ||
862 | const struct sk_buff *skb, | ||
863 | const char *proto) | ||
864 | { | ||
865 | const char *msg = "Dropping request"; | ||
866 | bool want_cookie = false; | ||
867 | struct listen_sock *lopt; | ||
868 | |||
869 | #ifdef CONFIG_SYN_COOKIES | ||
870 | if (sysctl_tcp_syncookies) { | ||
871 | msg = "Sending cookies"; | ||
872 | want_cookie = true; | ||
873 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPREQQFULLDOCOOKIES); | ||
874 | } else | ||
875 | #endif | ||
876 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPREQQFULLDROP); | ||
877 | |||
878 | lopt = inet_csk(sk)->icsk_accept_queue.listen_opt; | ||
879 | if (!lopt->synflood_warned && sysctl_tcp_syncookies != 2) { | ||
880 | lopt->synflood_warned = 1; | ||
881 | pr_info("%s: Possible SYN flooding on port %d. %s. Check SNMP counters.\n", | ||
882 | proto, ntohs(tcp_hdr(skb)->dest), msg); | ||
883 | } | ||
884 | return want_cookie; | ||
885 | } | ||
886 | EXPORT_SYMBOL(tcp_syn_flood_action); | ||
887 | 859 | ||
888 | #ifdef CONFIG_TCP_MD5SIG | 860 | #ifdef CONFIG_TCP_MD5SIG |
889 | /* | 861 | /* |
@@ -897,10 +869,10 @@ struct tcp_md5sig_key *tcp_md5_do_lookup(struct sock *sk, | |||
897 | const union tcp_md5_addr *addr, | 869 | const union tcp_md5_addr *addr, |
898 | int family) | 870 | int family) |
899 | { | 871 | { |
900 | struct tcp_sock *tp = tcp_sk(sk); | 872 | const struct tcp_sock *tp = tcp_sk(sk); |
901 | struct tcp_md5sig_key *key; | 873 | struct tcp_md5sig_key *key; |
902 | unsigned int size = sizeof(struct in_addr); | 874 | unsigned int size = sizeof(struct in_addr); |
903 | struct tcp_md5sig_info *md5sig; | 875 | const struct tcp_md5sig_info *md5sig; |
904 | 876 | ||
905 | /* caller either holds rcu_read_lock() or socket lock */ | 877 | /* caller either holds rcu_read_lock() or socket lock */ |
906 | md5sig = rcu_dereference_check(tp->md5sig_info, | 878 | md5sig = rcu_dereference_check(tp->md5sig_info, |
@@ -923,24 +895,15 @@ struct tcp_md5sig_key *tcp_md5_do_lookup(struct sock *sk, | |||
923 | EXPORT_SYMBOL(tcp_md5_do_lookup); | 895 | EXPORT_SYMBOL(tcp_md5_do_lookup); |
924 | 896 | ||
925 | struct tcp_md5sig_key *tcp_v4_md5_lookup(struct sock *sk, | 897 | struct tcp_md5sig_key *tcp_v4_md5_lookup(struct sock *sk, |
926 | struct sock *addr_sk) | 898 | const struct sock *addr_sk) |
927 | { | 899 | { |
928 | union tcp_md5_addr *addr; | 900 | const union tcp_md5_addr *addr; |
929 | 901 | ||
930 | addr = (union tcp_md5_addr *)&inet_sk(addr_sk)->inet_daddr; | 902 | addr = (const union tcp_md5_addr *)&addr_sk->sk_daddr; |
931 | return tcp_md5_do_lookup(sk, addr, AF_INET); | 903 | return tcp_md5_do_lookup(sk, addr, AF_INET); |
932 | } | 904 | } |
933 | EXPORT_SYMBOL(tcp_v4_md5_lookup); | 905 | EXPORT_SYMBOL(tcp_v4_md5_lookup); |
934 | 906 | ||
935 | static struct tcp_md5sig_key *tcp_v4_reqsk_md5_lookup(struct sock *sk, | ||
936 | struct request_sock *req) | ||
937 | { | ||
938 | union tcp_md5_addr *addr; | ||
939 | |||
940 | addr = (union tcp_md5_addr *)&inet_rsk(req)->ir_rmt_addr; | ||
941 | return tcp_md5_do_lookup(sk, addr, AF_INET); | ||
942 | } | ||
943 | |||
944 | /* This can be called on a newly created socket, from other files */ | 907 | /* This can be called on a newly created socket, from other files */ |
945 | int tcp_md5_do_add(struct sock *sk, const union tcp_md5_addr *addr, | 908 | int tcp_md5_do_add(struct sock *sk, const union tcp_md5_addr *addr, |
946 | int family, const u8 *newkey, u8 newkeylen, gfp_t gfp) | 909 | int family, const u8 *newkey, u8 newkeylen, gfp_t gfp) |
@@ -1101,8 +1064,8 @@ clear_hash_noput: | |||
1101 | return 1; | 1064 | return 1; |
1102 | } | 1065 | } |
1103 | 1066 | ||
1104 | int tcp_v4_md5_hash_skb(char *md5_hash, struct tcp_md5sig_key *key, | 1067 | int tcp_v4_md5_hash_skb(char *md5_hash, const struct tcp_md5sig_key *key, |
1105 | const struct sock *sk, const struct request_sock *req, | 1068 | const struct sock *sk, |
1106 | const struct sk_buff *skb) | 1069 | const struct sk_buff *skb) |
1107 | { | 1070 | { |
1108 | struct tcp_md5sig_pool *hp; | 1071 | struct tcp_md5sig_pool *hp; |
@@ -1110,12 +1073,9 @@ int tcp_v4_md5_hash_skb(char *md5_hash, struct tcp_md5sig_key *key, | |||
1110 | const struct tcphdr *th = tcp_hdr(skb); | 1073 | const struct tcphdr *th = tcp_hdr(skb); |
1111 | __be32 saddr, daddr; | 1074 | __be32 saddr, daddr; |
1112 | 1075 | ||
1113 | if (sk) { | 1076 | if (sk) { /* valid for establish/request sockets */ |
1114 | saddr = inet_sk(sk)->inet_saddr; | 1077 | saddr = sk->sk_rcv_saddr; |
1115 | daddr = inet_sk(sk)->inet_daddr; | 1078 | daddr = sk->sk_daddr; |
1116 | } else if (req) { | ||
1117 | saddr = inet_rsk(req)->ir_loc_addr; | ||
1118 | daddr = inet_rsk(req)->ir_rmt_addr; | ||
1119 | } else { | 1079 | } else { |
1120 | const struct iphdr *iph = ip_hdr(skb); | 1080 | const struct iphdr *iph = ip_hdr(skb); |
1121 | saddr = iph->saddr; | 1081 | saddr = iph->saddr; |
@@ -1152,8 +1112,9 @@ clear_hash_noput: | |||
1152 | } | 1112 | } |
1153 | EXPORT_SYMBOL(tcp_v4_md5_hash_skb); | 1113 | EXPORT_SYMBOL(tcp_v4_md5_hash_skb); |
1154 | 1114 | ||
1155 | static bool __tcp_v4_inbound_md5_hash(struct sock *sk, | 1115 | /* Called with rcu_read_lock() */ |
1156 | const struct sk_buff *skb) | 1116 | static bool tcp_v4_inbound_md5_hash(struct sock *sk, |
1117 | const struct sk_buff *skb) | ||
1157 | { | 1118 | { |
1158 | /* | 1119 | /* |
1159 | * This gets called for each TCP segment that arrives | 1120 | * This gets called for each TCP segment that arrives |
@@ -1193,7 +1154,7 @@ static bool __tcp_v4_inbound_md5_hash(struct sock *sk, | |||
1193 | */ | 1154 | */ |
1194 | genhash = tcp_v4_md5_hash_skb(newhash, | 1155 | genhash = tcp_v4_md5_hash_skb(newhash, |
1195 | hash_expected, | 1156 | hash_expected, |
1196 | NULL, NULL, skb); | 1157 | NULL, skb); |
1197 | 1158 | ||
1198 | if (genhash || memcmp(hash_location, newhash, 16) != 0) { | 1159 | if (genhash || memcmp(hash_location, newhash, 16) != 0) { |
1199 | net_info_ratelimited("MD5 Hash failed for (%pI4, %d)->(%pI4, %d)%s\n", | 1160 | net_info_ratelimited("MD5 Hash failed for (%pI4, %d)->(%pI4, %d)%s\n", |
@@ -1205,28 +1166,16 @@ static bool __tcp_v4_inbound_md5_hash(struct sock *sk, | |||
1205 | } | 1166 | } |
1206 | return false; | 1167 | return false; |
1207 | } | 1168 | } |
1208 | |||
1209 | static bool tcp_v4_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb) | ||
1210 | { | ||
1211 | bool ret; | ||
1212 | |||
1213 | rcu_read_lock(); | ||
1214 | ret = __tcp_v4_inbound_md5_hash(sk, skb); | ||
1215 | rcu_read_unlock(); | ||
1216 | |||
1217 | return ret; | ||
1218 | } | ||
1219 | |||
1220 | #endif | 1169 | #endif |
1221 | 1170 | ||
1222 | static void tcp_v4_init_req(struct request_sock *req, struct sock *sk, | 1171 | static void tcp_v4_init_req(struct request_sock *req, struct sock *sk_listener, |
1223 | struct sk_buff *skb) | 1172 | struct sk_buff *skb) |
1224 | { | 1173 | { |
1225 | struct inet_request_sock *ireq = inet_rsk(req); | 1174 | struct inet_request_sock *ireq = inet_rsk(req); |
1226 | 1175 | ||
1227 | ireq->ir_loc_addr = ip_hdr(skb)->daddr; | 1176 | sk_rcv_saddr_set(req_to_sk(req), ip_hdr(skb)->daddr); |
1228 | ireq->ir_rmt_addr = ip_hdr(skb)->saddr; | 1177 | sk_daddr_set(req_to_sk(req), ip_hdr(skb)->saddr); |
1229 | ireq->no_srccheck = inet_sk(sk)->transparent; | 1178 | ireq->no_srccheck = inet_sk(sk_listener)->transparent; |
1230 | ireq->opt = tcp_v4_save_options(skb); | 1179 | ireq->opt = tcp_v4_save_options(skb); |
1231 | } | 1180 | } |
1232 | 1181 | ||
@@ -1259,7 +1208,7 @@ struct request_sock_ops tcp_request_sock_ops __read_mostly = { | |||
1259 | static const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = { | 1208 | static const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = { |
1260 | .mss_clamp = TCP_MSS_DEFAULT, | 1209 | .mss_clamp = TCP_MSS_DEFAULT, |
1261 | #ifdef CONFIG_TCP_MD5SIG | 1210 | #ifdef CONFIG_TCP_MD5SIG |
1262 | .md5_lookup = tcp_v4_reqsk_md5_lookup, | 1211 | .req_md5_lookup = tcp_v4_md5_lookup, |
1263 | .calc_md5_hash = tcp_v4_md5_hash_skb, | 1212 | .calc_md5_hash = tcp_v4_md5_hash_skb, |
1264 | #endif | 1213 | #endif |
1265 | .init_req = tcp_v4_init_req, | 1214 | .init_req = tcp_v4_init_req, |
@@ -1318,8 +1267,8 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1318 | newtp = tcp_sk(newsk); | 1267 | newtp = tcp_sk(newsk); |
1319 | newinet = inet_sk(newsk); | 1268 | newinet = inet_sk(newsk); |
1320 | ireq = inet_rsk(req); | 1269 | ireq = inet_rsk(req); |
1321 | newinet->inet_daddr = ireq->ir_rmt_addr; | 1270 | sk_daddr_set(newsk, ireq->ir_rmt_addr); |
1322 | newinet->inet_rcv_saddr = ireq->ir_loc_addr; | 1271 | sk_rcv_saddr_set(newsk, ireq->ir_loc_addr); |
1323 | newinet->inet_saddr = ireq->ir_loc_addr; | 1272 | newinet->inet_saddr = ireq->ir_loc_addr; |
1324 | inet_opt = ireq->opt; | 1273 | inet_opt = ireq->opt; |
1325 | rcu_assign_pointer(newinet->inet_opt, inet_opt); | 1274 | rcu_assign_pointer(newinet->inet_opt, inet_opt); |
@@ -1356,7 +1305,7 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1356 | /* Copy over the MD5 key from the original socket */ | 1305 | /* Copy over the MD5 key from the original socket */ |
1357 | key = tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&newinet->inet_daddr, | 1306 | key = tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&newinet->inet_daddr, |
1358 | AF_INET); | 1307 | AF_INET); |
1359 | if (key != NULL) { | 1308 | if (key) { |
1360 | /* | 1309 | /* |
1361 | * We're using one, so create a matching key | 1310 | * We're using one, so create a matching key |
1362 | * on the newsk structure. If we fail to get | 1311 | * on the newsk structure. If we fail to get |
@@ -1391,15 +1340,17 @@ EXPORT_SYMBOL(tcp_v4_syn_recv_sock); | |||
1391 | 1340 | ||
1392 | static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb) | 1341 | static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb) |
1393 | { | 1342 | { |
1394 | struct tcphdr *th = tcp_hdr(skb); | 1343 | const struct tcphdr *th = tcp_hdr(skb); |
1395 | const struct iphdr *iph = ip_hdr(skb); | 1344 | const struct iphdr *iph = ip_hdr(skb); |
1345 | struct request_sock *req; | ||
1396 | struct sock *nsk; | 1346 | struct sock *nsk; |
1397 | struct request_sock **prev; | 1347 | |
1398 | /* Find possible connection requests. */ | 1348 | req = inet_csk_search_req(sk, th->source, iph->saddr, iph->daddr); |
1399 | struct request_sock *req = inet_csk_search_req(sk, &prev, th->source, | 1349 | if (req) { |
1400 | iph->saddr, iph->daddr); | 1350 | nsk = tcp_check_req(sk, skb, req, false); |
1401 | if (req) | 1351 | reqsk_put(req); |
1402 | return tcp_check_req(sk, skb, req, prev, false); | 1352 | return nsk; |
1353 | } | ||
1403 | 1354 | ||
1404 | nsk = inet_lookup_established(sock_net(sk), &tcp_hashinfo, iph->saddr, | 1355 | nsk = inet_lookup_established(sock_net(sk), &tcp_hashinfo, iph->saddr, |
1405 | th->source, iph->daddr, th->dest, inet_iif(skb)); | 1356 | th->source, iph->daddr, th->dest, inet_iif(skb)); |
@@ -1439,7 +1390,7 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb) | |||
1439 | sk_mark_napi_id(sk, skb); | 1390 | sk_mark_napi_id(sk, skb); |
1440 | if (dst) { | 1391 | if (dst) { |
1441 | if (inet_sk(sk)->rx_dst_ifindex != skb->skb_iif || | 1392 | if (inet_sk(sk)->rx_dst_ifindex != skb->skb_iif || |
1442 | dst->ops->check(dst, 0) == NULL) { | 1393 | !dst->ops->check(dst, 0)) { |
1443 | dst_release(dst); | 1394 | dst_release(dst); |
1444 | sk->sk_rx_dst = NULL; | 1395 | sk->sk_rx_dst = NULL; |
1445 | } | 1396 | } |
@@ -1517,7 +1468,7 @@ void tcp_v4_early_demux(struct sk_buff *skb) | |||
1517 | if (sk) { | 1468 | if (sk) { |
1518 | skb->sk = sk; | 1469 | skb->sk = sk; |
1519 | skb->destructor = sock_edemux; | 1470 | skb->destructor = sock_edemux; |
1520 | if (sk->sk_state != TCP_TIME_WAIT) { | 1471 | if (sk_fullsock(sk)) { |
1521 | struct dst_entry *dst = READ_ONCE(sk->sk_rx_dst); | 1472 | struct dst_entry *dst = READ_ONCE(sk->sk_rx_dst); |
1522 | 1473 | ||
1523 | if (dst) | 1474 | if (dst) |
@@ -1734,7 +1685,7 @@ do_time_wait: | |||
1734 | iph->daddr, th->dest, | 1685 | iph->daddr, th->dest, |
1735 | inet_iif(skb)); | 1686 | inet_iif(skb)); |
1736 | if (sk2) { | 1687 | if (sk2) { |
1737 | inet_twsk_deschedule(inet_twsk(sk), &tcp_death_row); | 1688 | inet_twsk_deschedule(inet_twsk(sk)); |
1738 | inet_twsk_put(inet_twsk(sk)); | 1689 | inet_twsk_put(inet_twsk(sk)); |
1739 | sk = sk2; | 1690 | sk = sk2; |
1740 | goto process; | 1691 | goto process; |
@@ -1846,7 +1797,7 @@ void tcp_v4_destroy_sock(struct sock *sk) | |||
1846 | if (inet_csk(sk)->icsk_bind_hash) | 1797 | if (inet_csk(sk)->icsk_bind_hash) |
1847 | inet_put_port(sk); | 1798 | inet_put_port(sk); |
1848 | 1799 | ||
1849 | BUG_ON(tp->fastopen_rsk != NULL); | 1800 | BUG_ON(tp->fastopen_rsk); |
1850 | 1801 | ||
1851 | /* If socket is aborted during connect operation */ | 1802 | /* If socket is aborted during connect operation */ |
1852 | tcp_free_fastopen_req(tp); | 1803 | tcp_free_fastopen_req(tp); |
@@ -1904,13 +1855,13 @@ get_req: | |||
1904 | } | 1855 | } |
1905 | sk = sk_nulls_next(st->syn_wait_sk); | 1856 | sk = sk_nulls_next(st->syn_wait_sk); |
1906 | st->state = TCP_SEQ_STATE_LISTENING; | 1857 | st->state = TCP_SEQ_STATE_LISTENING; |
1907 | read_unlock_bh(&icsk->icsk_accept_queue.syn_wait_lock); | 1858 | spin_unlock_bh(&icsk->icsk_accept_queue.syn_wait_lock); |
1908 | } else { | 1859 | } else { |
1909 | icsk = inet_csk(sk); | 1860 | icsk = inet_csk(sk); |
1910 | read_lock_bh(&icsk->icsk_accept_queue.syn_wait_lock); | 1861 | spin_lock_bh(&icsk->icsk_accept_queue.syn_wait_lock); |
1911 | if (reqsk_queue_len(&icsk->icsk_accept_queue)) | 1862 | if (reqsk_queue_len(&icsk->icsk_accept_queue)) |
1912 | goto start_req; | 1863 | goto start_req; |
1913 | read_unlock_bh(&icsk->icsk_accept_queue.syn_wait_lock); | 1864 | spin_unlock_bh(&icsk->icsk_accept_queue.syn_wait_lock); |
1914 | sk = sk_nulls_next(sk); | 1865 | sk = sk_nulls_next(sk); |
1915 | } | 1866 | } |
1916 | get_sk: | 1867 | get_sk: |
@@ -1922,7 +1873,7 @@ get_sk: | |||
1922 | goto out; | 1873 | goto out; |
1923 | } | 1874 | } |
1924 | icsk = inet_csk(sk); | 1875 | icsk = inet_csk(sk); |
1925 | read_lock_bh(&icsk->icsk_accept_queue.syn_wait_lock); | 1876 | spin_lock_bh(&icsk->icsk_accept_queue.syn_wait_lock); |
1926 | if (reqsk_queue_len(&icsk->icsk_accept_queue)) { | 1877 | if (reqsk_queue_len(&icsk->icsk_accept_queue)) { |
1927 | start_req: | 1878 | start_req: |
1928 | st->uid = sock_i_uid(sk); | 1879 | st->uid = sock_i_uid(sk); |
@@ -1931,7 +1882,7 @@ start_req: | |||
1931 | st->sbucket = 0; | 1882 | st->sbucket = 0; |
1932 | goto get_req; | 1883 | goto get_req; |
1933 | } | 1884 | } |
1934 | read_unlock_bh(&icsk->icsk_accept_queue.syn_wait_lock); | 1885 | spin_unlock_bh(&icsk->icsk_accept_queue.syn_wait_lock); |
1935 | } | 1886 | } |
1936 | spin_unlock_bh(&ilb->lock); | 1887 | spin_unlock_bh(&ilb->lock); |
1937 | st->offset = 0; | 1888 | st->offset = 0; |
@@ -2150,7 +2101,7 @@ static void tcp_seq_stop(struct seq_file *seq, void *v) | |||
2150 | case TCP_SEQ_STATE_OPENREQ: | 2101 | case TCP_SEQ_STATE_OPENREQ: |
2151 | if (v) { | 2102 | if (v) { |
2152 | struct inet_connection_sock *icsk = inet_csk(st->syn_wait_sk); | 2103 | struct inet_connection_sock *icsk = inet_csk(st->syn_wait_sk); |
2153 | read_unlock_bh(&icsk->icsk_accept_queue.syn_wait_lock); | 2104 | spin_unlock_bh(&icsk->icsk_accept_queue.syn_wait_lock); |
2154 | } | 2105 | } |
2155 | case TCP_SEQ_STATE_LISTENING: | 2106 | case TCP_SEQ_STATE_LISTENING: |
2156 | if (v != SEQ_START_TOKEN) | 2107 | if (v != SEQ_START_TOKEN) |
@@ -2204,17 +2155,17 @@ void tcp_proc_unregister(struct net *net, struct tcp_seq_afinfo *afinfo) | |||
2204 | } | 2155 | } |
2205 | EXPORT_SYMBOL(tcp_proc_unregister); | 2156 | EXPORT_SYMBOL(tcp_proc_unregister); |
2206 | 2157 | ||
2207 | static void get_openreq4(const struct sock *sk, const struct request_sock *req, | 2158 | static void get_openreq4(const struct request_sock *req, |
2208 | struct seq_file *f, int i, kuid_t uid) | 2159 | struct seq_file *f, int i, kuid_t uid) |
2209 | { | 2160 | { |
2210 | const struct inet_request_sock *ireq = inet_rsk(req); | 2161 | const struct inet_request_sock *ireq = inet_rsk(req); |
2211 | long delta = req->expires - jiffies; | 2162 | long delta = req->rsk_timer.expires - jiffies; |
2212 | 2163 | ||
2213 | seq_printf(f, "%4d: %08X:%04X %08X:%04X" | 2164 | seq_printf(f, "%4d: %08X:%04X %08X:%04X" |
2214 | " %02X %08X:%08X %02X:%08lX %08X %5u %8d %u %d %pK", | 2165 | " %02X %08X:%08X %02X:%08lX %08X %5u %8d %u %d %pK", |
2215 | i, | 2166 | i, |
2216 | ireq->ir_loc_addr, | 2167 | ireq->ir_loc_addr, |
2217 | ntohs(inet_sk(sk)->inet_sport), | 2168 | ireq->ir_num, |
2218 | ireq->ir_rmt_addr, | 2169 | ireq->ir_rmt_addr, |
2219 | ntohs(ireq->ir_rmt_port), | 2170 | ntohs(ireq->ir_rmt_port), |
2220 | TCP_SYN_RECV, | 2171 | TCP_SYN_RECV, |
@@ -2225,7 +2176,7 @@ static void get_openreq4(const struct sock *sk, const struct request_sock *req, | |||
2225 | from_kuid_munged(seq_user_ns(f), uid), | 2176 | from_kuid_munged(seq_user_ns(f), uid), |
2226 | 0, /* non standard timer */ | 2177 | 0, /* non standard timer */ |
2227 | 0, /* open_requests have no inode */ | 2178 | 0, /* open_requests have no inode */ |
2228 | atomic_read(&sk->sk_refcnt), | 2179 | 0, |
2229 | req); | 2180 | req); |
2230 | } | 2181 | } |
2231 | 2182 | ||
@@ -2291,9 +2242,9 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i) | |||
2291 | static void get_timewait4_sock(const struct inet_timewait_sock *tw, | 2242 | static void get_timewait4_sock(const struct inet_timewait_sock *tw, |
2292 | struct seq_file *f, int i) | 2243 | struct seq_file *f, int i) |
2293 | { | 2244 | { |
2245 | long delta = tw->tw_timer.expires - jiffies; | ||
2294 | __be32 dest, src; | 2246 | __be32 dest, src; |
2295 | __u16 destp, srcp; | 2247 | __u16 destp, srcp; |
2296 | s32 delta = tw->tw_ttd - inet_tw_time_stamp(); | ||
2297 | 2248 | ||
2298 | dest = tw->tw_daddr; | 2249 | dest = tw->tw_daddr; |
2299 | src = tw->tw_rcv_saddr; | 2250 | src = tw->tw_rcv_saddr; |
@@ -2332,7 +2283,7 @@ static int tcp4_seq_show(struct seq_file *seq, void *v) | |||
2332 | get_tcp4_sock(v, seq, st->num); | 2283 | get_tcp4_sock(v, seq, st->num); |
2333 | break; | 2284 | break; |
2334 | case TCP_SEQ_STATE_OPENREQ: | 2285 | case TCP_SEQ_STATE_OPENREQ: |
2335 | get_openreq4(st->syn_wait_sk, v, seq, st->num, st->uid); | 2286 | get_openreq4(v, seq, st->num, st->uid); |
2336 | break; | 2287 | break; |
2337 | } | 2288 | } |
2338 | out: | 2289 | out: |
@@ -2460,6 +2411,8 @@ static int __net_init tcp_sk_init(struct net *net) | |||
2460 | } | 2411 | } |
2461 | net->ipv4.sysctl_tcp_ecn = 2; | 2412 | net->ipv4.sysctl_tcp_ecn = 2; |
2462 | net->ipv4.sysctl_tcp_base_mss = TCP_BASE_MSS; | 2413 | net->ipv4.sysctl_tcp_base_mss = TCP_BASE_MSS; |
2414 | net->ipv4.sysctl_tcp_probe_threshold = TCP_PROBE_THRESHOLD; | ||
2415 | net->ipv4.sysctl_tcp_probe_interval = TCP_PROBE_INTERVAL; | ||
2463 | return 0; | 2416 | return 0; |
2464 | 2417 | ||
2465 | fail: | 2418 | fail: |