aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/tcp_ipv6.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r--net/ipv6/tcp_ipv6.c204
1 files changed, 56 insertions, 148 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 9df64a50b075..f49476e2d884 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -277,22 +277,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
277 rt = (struct rt6_info *) dst; 277 rt = (struct rt6_info *) dst;
278 if (tcp_death_row.sysctl_tw_recycle && 278 if (tcp_death_row.sysctl_tw_recycle &&
279 !tp->rx_opt.ts_recent_stamp && 279 !tp->rx_opt.ts_recent_stamp &&
280 ipv6_addr_equal(&rt->rt6i_dst.addr, &np->daddr)) { 280 ipv6_addr_equal(&rt->rt6i_dst.addr, &np->daddr))
281 struct inet_peer *peer = rt6_get_peer(rt); 281 tcp_fetch_timewait_stamp(sk, dst);
282 /*
283 * VJ's idea. We save last timestamp seen from
284 * the destination in peer table, when entering state
285 * TIME-WAIT * and initialize rx_opt.ts_recent from it,
286 * when trying new connection.
287 */
288 if (peer) {
289 inet_peer_refcheck(peer);
290 if ((u32)get_seconds() - peer->tcp_ts_stamp <= TCP_PAWS_MSL) {
291 tp->rx_opt.ts_recent_stamp = peer->tcp_ts_stamp;
292 tp->rx_opt.ts_recent = peer->tcp_ts;
293 }
294 }
295 }
296 282
297 icsk->icsk_ext_hdr_len = 0; 283 icsk->icsk_ext_hdr_len = 0;
298 if (np->opt) 284 if (np->opt)
@@ -329,6 +315,23 @@ failure:
329 return err; 315 return err;
330} 316}
331 317
318static void tcp_v6_mtu_reduced(struct sock *sk)
319{
320 struct dst_entry *dst;
321
322 if ((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE))
323 return;
324
325 dst = inet6_csk_update_pmtu(sk, tcp_sk(sk)->mtu_info);
326 if (!dst)
327 return;
328
329 if (inet_csk(sk)->icsk_pmtu_cookie > dst_mtu(dst)) {
330 tcp_sync_mss(sk, dst_mtu(dst));
331 tcp_simple_retransmit(sk);
332 }
333}
334
332static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 335static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
333 u8 type, u8 code, int offset, __be32 info) 336 u8 type, u8 code, int offset, __be32 info)
334{ 337{
@@ -356,7 +359,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
356 } 359 }
357 360
358 bh_lock_sock(sk); 361 bh_lock_sock(sk);
359 if (sock_owned_by_user(sk)) 362 if (sock_owned_by_user(sk) && type != ICMPV6_PKT_TOOBIG)
360 NET_INC_STATS_BH(net, LINUX_MIB_LOCKDROPPEDICMPS); 363 NET_INC_STATS_BH(net, LINUX_MIB_LOCKDROPPEDICMPS);
361 364
362 if (sk->sk_state == TCP_CLOSE) 365 if (sk->sk_state == TCP_CLOSE)
@@ -377,49 +380,19 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
377 380
378 np = inet6_sk(sk); 381 np = inet6_sk(sk);
379 382
380 if (type == ICMPV6_PKT_TOOBIG) { 383 if (type == NDISC_REDIRECT) {
381 struct dst_entry *dst; 384 struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie);
382
383 if (sock_owned_by_user(sk))
384 goto out;
385 if ((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE))
386 goto out;
387
388 /* icmp should have updated the destination cache entry */
389 dst = __sk_dst_check(sk, np->dst_cookie);
390
391 if (dst == NULL) {
392 struct inet_sock *inet = inet_sk(sk);
393 struct flowi6 fl6;
394
395 /* BUGGG_FUTURE: Again, it is not clear how
396 to handle rthdr case. Ignore this complexity
397 for now.
398 */
399 memset(&fl6, 0, sizeof(fl6));
400 fl6.flowi6_proto = IPPROTO_TCP;
401 fl6.daddr = np->daddr;
402 fl6.saddr = np->saddr;
403 fl6.flowi6_oif = sk->sk_bound_dev_if;
404 fl6.flowi6_mark = sk->sk_mark;
405 fl6.fl6_dport = inet->inet_dport;
406 fl6.fl6_sport = inet->inet_sport;
407 security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
408
409 dst = ip6_dst_lookup_flow(sk, &fl6, NULL, false);
410 if (IS_ERR(dst)) {
411 sk->sk_err_soft = -PTR_ERR(dst);
412 goto out;
413 }
414 385
415 } else 386 if (dst)
416 dst_hold(dst); 387 dst->ops->redirect(dst, sk, skb);
388 }
417 389
418 if (inet_csk(sk)->icsk_pmtu_cookie > dst_mtu(dst)) { 390 if (type == ICMPV6_PKT_TOOBIG) {
419 tcp_sync_mss(sk, dst_mtu(dst)); 391 tp->mtu_info = ntohl(info);
420 tcp_simple_retransmit(sk); 392 if (!sock_owned_by_user(sk))
421 } /* else let the usual retransmit timer handle it */ 393 tcp_v6_mtu_reduced(sk);
422 dst_release(dst); 394 else
395 set_bit(TCP_MTU_REDUCED_DEFERRED, &tp->tsq_flags);
423 goto out; 396 goto out;
424 } 397 }
425 398
@@ -475,62 +448,43 @@ out:
475} 448}
476 449
477 450
478static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req, 451static int tcp_v6_send_synack(struct sock *sk, struct dst_entry *dst,
452 struct flowi6 *fl6,
453 struct request_sock *req,
479 struct request_values *rvp, 454 struct request_values *rvp,
480 u16 queue_mapping) 455 u16 queue_mapping)
481{ 456{
482 struct inet6_request_sock *treq = inet6_rsk(req); 457 struct inet6_request_sock *treq = inet6_rsk(req);
483 struct ipv6_pinfo *np = inet6_sk(sk); 458 struct ipv6_pinfo *np = inet6_sk(sk);
484 struct sk_buff * skb; 459 struct sk_buff * skb;
485 struct ipv6_txoptions *opt = NULL; 460 int err = -ENOMEM;
486 struct in6_addr * final_p, final;
487 struct flowi6 fl6;
488 struct dst_entry *dst;
489 int err;
490 461
491 memset(&fl6, 0, sizeof(fl6)); 462 /* First, grab a route. */
492 fl6.flowi6_proto = IPPROTO_TCP; 463 if (!dst && (dst = inet6_csk_route_req(sk, fl6, req)) == NULL)
493 fl6.daddr = treq->rmt_addr;
494 fl6.saddr = treq->loc_addr;
495 fl6.flowlabel = 0;
496 fl6.flowi6_oif = treq->iif;
497 fl6.flowi6_mark = sk->sk_mark;
498 fl6.fl6_dport = inet_rsk(req)->rmt_port;
499 fl6.fl6_sport = inet_rsk(req)->loc_port;
500 security_req_classify_flow(req, flowi6_to_flowi(&fl6));
501
502 opt = np->opt;
503 final_p = fl6_update_dst(&fl6, opt, &final);
504
505 dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false);
506 if (IS_ERR(dst)) {
507 err = PTR_ERR(dst);
508 dst = NULL;
509 goto done; 464 goto done;
510 } 465
511 skb = tcp_make_synack(sk, dst, req, rvp); 466 skb = tcp_make_synack(sk, dst, req, rvp);
512 err = -ENOMEM; 467
513 if (skb) { 468 if (skb) {
514 __tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr); 469 __tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr);
515 470
516 fl6.daddr = treq->rmt_addr; 471 fl6->daddr = treq->rmt_addr;
517 skb_set_queue_mapping(skb, queue_mapping); 472 skb_set_queue_mapping(skb, queue_mapping);
518 err = ip6_xmit(sk, skb, &fl6, opt, np->tclass); 473 err = ip6_xmit(sk, skb, fl6, np->opt, np->tclass);
519 err = net_xmit_eval(err); 474 err = net_xmit_eval(err);
520 } 475 }
521 476
522done: 477done:
523 if (opt && opt != np->opt)
524 sock_kfree_s(sk, opt, opt->tot_len);
525 dst_release(dst);
526 return err; 478 return err;
527} 479}
528 480
529static int tcp_v6_rtx_synack(struct sock *sk, struct request_sock *req, 481static int tcp_v6_rtx_synack(struct sock *sk, struct request_sock *req,
530 struct request_values *rvp) 482 struct request_values *rvp)
531{ 483{
484 struct flowi6 fl6;
485
532 TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS); 486 TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS);
533 return tcp_v6_send_synack(sk, req, rvp, 0); 487 return tcp_v6_send_synack(sk, NULL, &fl6, req, rvp, 0);
534} 488}
535 489
536static void tcp_v6_reqsk_destructor(struct request_sock *req) 490static void tcp_v6_reqsk_destructor(struct request_sock *req)
@@ -1057,6 +1011,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1057 struct tcp_sock *tp = tcp_sk(sk); 1011 struct tcp_sock *tp = tcp_sk(sk);
1058 __u32 isn = TCP_SKB_CB(skb)->when; 1012 __u32 isn = TCP_SKB_CB(skb)->when;
1059 struct dst_entry *dst = NULL; 1013 struct dst_entry *dst = NULL;
1014 struct flowi6 fl6;
1060 bool want_cookie = false; 1015 bool want_cookie = false;
1061 1016
1062 if (skb->protocol == htons(ETH_P_IP)) 1017 if (skb->protocol == htons(ETH_P_IP))
@@ -1085,7 +1040,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1085 tcp_clear_options(&tmp_opt); 1040 tcp_clear_options(&tmp_opt);
1086 tmp_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr); 1041 tmp_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
1087 tmp_opt.user_mss = tp->rx_opt.user_mss; 1042 tmp_opt.user_mss = tp->rx_opt.user_mss;
1088 tcp_parse_options(skb, &tmp_opt, &hash_location, 0); 1043 tcp_parse_options(skb, &tmp_opt, &hash_location, 0, NULL);
1089 1044
1090 if (tmp_opt.cookie_plus > 0 && 1045 if (tmp_opt.cookie_plus > 0 &&
1091 tmp_opt.saw_tstamp && 1046 tmp_opt.saw_tstamp &&
@@ -1150,8 +1105,6 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1150 treq->iif = inet6_iif(skb); 1105 treq->iif = inet6_iif(skb);
1151 1106
1152 if (!isn) { 1107 if (!isn) {
1153 struct inet_peer *peer = NULL;
1154
1155 if (ipv6_opt_accepted(sk, skb) || 1108 if (ipv6_opt_accepted(sk, skb) ||
1156 np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo || 1109 np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo ||
1157 np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) { 1110 np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) {
@@ -1176,14 +1129,8 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1176 */ 1129 */
1177 if (tmp_opt.saw_tstamp && 1130 if (tmp_opt.saw_tstamp &&
1178 tcp_death_row.sysctl_tw_recycle && 1131 tcp_death_row.sysctl_tw_recycle &&
1179 (dst = inet6_csk_route_req(sk, req)) != NULL && 1132 (dst = inet6_csk_route_req(sk, &fl6, req)) != NULL) {
1180 (peer = rt6_get_peer((struct rt6_info *)dst)) != NULL && 1133 if (!tcp_peer_is_proven(req, dst, true)) {
1181 ipv6_addr_equal((struct in6_addr *)peer->daddr.addr.a6,
1182 &treq->rmt_addr)) {
1183 inet_peer_refcheck(peer);
1184 if ((u32)get_seconds() - peer->tcp_ts_stamp < TCP_PAWS_MSL &&
1185 (s32)(peer->tcp_ts - req->ts_recent) >
1186 TCP_PAWS_WINDOW) {
1187 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_PAWSPASSIVEREJECTED); 1134 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_PAWSPASSIVEREJECTED);
1188 goto drop_and_release; 1135 goto drop_and_release;
1189 } 1136 }
@@ -1192,8 +1139,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1192 else if (!sysctl_tcp_syncookies && 1139 else if (!sysctl_tcp_syncookies &&
1193 (sysctl_max_syn_backlog - inet_csk_reqsk_queue_len(sk) < 1140 (sysctl_max_syn_backlog - inet_csk_reqsk_queue_len(sk) <
1194 (sysctl_max_syn_backlog >> 2)) && 1141 (sysctl_max_syn_backlog >> 2)) &&
1195 (!peer || !peer->tcp_ts_stamp) && 1142 !tcp_peer_is_proven(req, dst, false)) {
1196 (!dst || !dst_metric(dst, RTAX_RTT))) {
1197 /* Without syncookies last quarter of 1143 /* Without syncookies last quarter of
1198 * backlog is filled with destinations, 1144 * backlog is filled with destinations,
1199 * proven to be alive. 1145 * proven to be alive.
@@ -1215,7 +1161,7 @@ have_isn:
1215 if (security_inet_conn_request(sk, skb, req)) 1161 if (security_inet_conn_request(sk, skb, req))
1216 goto drop_and_release; 1162 goto drop_and_release;
1217 1163
1218 if (tcp_v6_send_synack(sk, req, 1164 if (tcp_v6_send_synack(sk, dst, &fl6, req,
1219 (struct request_values *)&tmp_ext, 1165 (struct request_values *)&tmp_ext,
1220 skb_get_queue_mapping(skb)) || 1166 skb_get_queue_mapping(skb)) ||
1221 want_cookie) 1167 want_cookie)
@@ -1242,10 +1188,10 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1242 struct inet_sock *newinet; 1188 struct inet_sock *newinet;
1243 struct tcp_sock *newtp; 1189 struct tcp_sock *newtp;
1244 struct sock *newsk; 1190 struct sock *newsk;
1245 struct ipv6_txoptions *opt;
1246#ifdef CONFIG_TCP_MD5SIG 1191#ifdef CONFIG_TCP_MD5SIG
1247 struct tcp_md5sig_key *key; 1192 struct tcp_md5sig_key *key;
1248#endif 1193#endif
1194 struct flowi6 fl6;
1249 1195
1250 if (skb->protocol == htons(ETH_P_IP)) { 1196 if (skb->protocol == htons(ETH_P_IP)) {
1251 /* 1197 /*
@@ -1302,13 +1248,12 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1302 } 1248 }
1303 1249
1304 treq = inet6_rsk(req); 1250 treq = inet6_rsk(req);
1305 opt = np->opt;
1306 1251
1307 if (sk_acceptq_is_full(sk)) 1252 if (sk_acceptq_is_full(sk))
1308 goto out_overflow; 1253 goto out_overflow;
1309 1254
1310 if (!dst) { 1255 if (!dst) {
1311 dst = inet6_csk_route_req(sk, req); 1256 dst = inet6_csk_route_req(sk, &fl6, req);
1312 if (!dst) 1257 if (!dst)
1313 goto out; 1258 goto out;
1314 } 1259 }
@@ -1371,11 +1316,8 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1371 but we make one more one thing there: reattach optmem 1316 but we make one more one thing there: reattach optmem
1372 to newsk. 1317 to newsk.
1373 */ 1318 */
1374 if (opt) { 1319 if (np->opt)
1375 newnp->opt = ipv6_dup_options(newsk, opt); 1320 newnp->opt = ipv6_dup_options(newsk, np->opt);
1376 if (opt != np->opt)
1377 sock_kfree_s(sk, opt, opt->tot_len);
1378 }
1379 1321
1380 inet_csk(newsk)->icsk_ext_hdr_len = 0; 1322 inet_csk(newsk)->icsk_ext_hdr_len = 0;
1381 if (newnp->opt) 1323 if (newnp->opt)
@@ -1422,8 +1364,6 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1422out_overflow: 1364out_overflow:
1423 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS); 1365 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS);
1424out_nonewsk: 1366out_nonewsk:
1425 if (opt && opt != np->opt)
1426 sock_kfree_s(sk, opt, opt->tot_len);
1427 dst_release(dst); 1367 dst_release(dst);
1428out: 1368out:
1429 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); 1369 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
@@ -1734,42 +1674,10 @@ do_time_wait:
1734 goto discard_it; 1674 goto discard_it;
1735} 1675}
1736 1676
1737static struct inet_peer *tcp_v6_get_peer(struct sock *sk, bool *release_it)
1738{
1739 struct rt6_info *rt = (struct rt6_info *) __sk_dst_get(sk);
1740 struct ipv6_pinfo *np = inet6_sk(sk);
1741 struct inet_peer *peer;
1742
1743 if (!rt ||
1744 !ipv6_addr_equal(&np->daddr, &rt->rt6i_dst.addr)) {
1745 peer = inet_getpeer_v6(&np->daddr, 1);
1746 *release_it = true;
1747 } else {
1748 if (!rt->rt6i_peer)
1749 rt6_bind_peer(rt, 1);
1750 peer = rt->rt6i_peer;
1751 *release_it = false;
1752 }
1753
1754 return peer;
1755}
1756
1757static void *tcp_v6_tw_get_peer(struct sock *sk)
1758{
1759 const struct inet6_timewait_sock *tw6 = inet6_twsk(sk);
1760 const struct inet_timewait_sock *tw = inet_twsk(sk);
1761
1762 if (tw->tw_family == AF_INET)
1763 return tcp_v4_tw_get_peer(sk);
1764
1765 return inet_getpeer_v6(&tw6->tw_v6_daddr, 1);
1766}
1767
1768static struct timewait_sock_ops tcp6_timewait_sock_ops = { 1677static struct timewait_sock_ops tcp6_timewait_sock_ops = {
1769 .twsk_obj_size = sizeof(struct tcp6_timewait_sock), 1678 .twsk_obj_size = sizeof(struct tcp6_timewait_sock),
1770 .twsk_unique = tcp_twsk_unique, 1679 .twsk_unique = tcp_twsk_unique,
1771 .twsk_destructor= tcp_twsk_destructor, 1680 .twsk_destructor= tcp_twsk_destructor,
1772 .twsk_getpeer = tcp_v6_tw_get_peer,
1773}; 1681};
1774 1682
1775static const struct inet_connection_sock_af_ops ipv6_specific = { 1683static const struct inet_connection_sock_af_ops ipv6_specific = {
@@ -1778,7 +1686,6 @@ static const struct inet_connection_sock_af_ops ipv6_specific = {
1778 .rebuild_header = inet6_sk_rebuild_header, 1686 .rebuild_header = inet6_sk_rebuild_header,
1779 .conn_request = tcp_v6_conn_request, 1687 .conn_request = tcp_v6_conn_request,
1780 .syn_recv_sock = tcp_v6_syn_recv_sock, 1688 .syn_recv_sock = tcp_v6_syn_recv_sock,
1781 .get_peer = tcp_v6_get_peer,
1782 .net_header_len = sizeof(struct ipv6hdr), 1689 .net_header_len = sizeof(struct ipv6hdr),
1783 .net_frag_header_len = sizeof(struct frag_hdr), 1690 .net_frag_header_len = sizeof(struct frag_hdr),
1784 .setsockopt = ipv6_setsockopt, 1691 .setsockopt = ipv6_setsockopt,
@@ -1810,7 +1717,6 @@ static const struct inet_connection_sock_af_ops ipv6_mapped = {
1810 .rebuild_header = inet_sk_rebuild_header, 1717 .rebuild_header = inet_sk_rebuild_header,
1811 .conn_request = tcp_v6_conn_request, 1718 .conn_request = tcp_v6_conn_request,
1812 .syn_recv_sock = tcp_v6_syn_recv_sock, 1719 .syn_recv_sock = tcp_v6_syn_recv_sock,
1813 .get_peer = tcp_v4_get_peer,
1814 .net_header_len = sizeof(struct iphdr), 1720 .net_header_len = sizeof(struct iphdr),
1815 .setsockopt = ipv6_setsockopt, 1721 .setsockopt = ipv6_setsockopt,
1816 .getsockopt = ipv6_getsockopt, 1722 .getsockopt = ipv6_getsockopt,
@@ -2049,6 +1955,8 @@ struct proto tcpv6_prot = {
2049 .sendmsg = tcp_sendmsg, 1955 .sendmsg = tcp_sendmsg,
2050 .sendpage = tcp_sendpage, 1956 .sendpage = tcp_sendpage,
2051 .backlog_rcv = tcp_v6_do_rcv, 1957 .backlog_rcv = tcp_v6_do_rcv,
1958 .release_cb = tcp_release_cb,
1959 .mtu_reduced = tcp_v6_mtu_reduced,
2052 .hash = tcp_v6_hash, 1960 .hash = tcp_v6_hash,
2053 .unhash = inet_unhash, 1961 .unhash = inet_unhash,
2054 .get_port = inet_csk_get_port, 1962 .get_port = inet_csk_get_port,