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.c50
1 files changed, 18 insertions, 32 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 87551ca568c..cdbce216521 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -61,6 +61,7 @@
61#include <net/timewait_sock.h> 61#include <net/timewait_sock.h>
62#include <net/netdma.h> 62#include <net/netdma.h>
63#include <net/inet_common.h> 63#include <net/inet_common.h>
64#include <net/secure_seq.h>
64 65
65#include <asm/uaccess.h> 66#include <asm/uaccess.h>
66 67
@@ -530,20 +531,6 @@ static int tcp_v6_rtx_synack(struct sock *sk, struct request_sock *req,
530 return tcp_v6_send_synack(sk, req, rvp); 531 return tcp_v6_send_synack(sk, req, rvp);
531} 532}
532 533
533static inline void syn_flood_warning(struct sk_buff *skb)
534{
535#ifdef CONFIG_SYN_COOKIES
536 if (sysctl_tcp_syncookies)
537 printk(KERN_INFO
538 "TCPv6: Possible SYN flooding on port %d. "
539 "Sending cookies.\n", ntohs(tcp_hdr(skb)->dest));
540 else
541#endif
542 printk(KERN_INFO
543 "TCPv6: Possible SYN flooding on port %d. "
544 "Dropping request.\n", ntohs(tcp_hdr(skb)->dest));
545}
546
547static void tcp_v6_reqsk_destructor(struct request_sock *req) 534static void tcp_v6_reqsk_destructor(struct request_sock *req)
548{ 535{
549 kfree_skb(inet6_rsk(req)->pktopts); 536 kfree_skb(inet6_rsk(req)->pktopts);
@@ -604,7 +591,8 @@ static int tcp_v6_md5_do_add(struct sock *sk, const struct in6_addr *peer,
604 } 591 }
605 sk_nocaps_add(sk, NETIF_F_GSO_MASK); 592 sk_nocaps_add(sk, NETIF_F_GSO_MASK);
606 } 593 }
607 if (tcp_alloc_md5sig_pool(sk) == NULL) { 594 if (tp->md5sig_info->entries6 == 0 &&
595 tcp_alloc_md5sig_pool(sk) == NULL) {
608 kfree(newkey); 596 kfree(newkey);
609 return -ENOMEM; 597 return -ENOMEM;
610 } 598 }
@@ -613,8 +601,9 @@ static int tcp_v6_md5_do_add(struct sock *sk, const struct in6_addr *peer,
613 (tp->md5sig_info->entries6 + 1)), GFP_ATOMIC); 601 (tp->md5sig_info->entries6 + 1)), GFP_ATOMIC);
614 602
615 if (!keys) { 603 if (!keys) {
616 tcp_free_md5sig_pool();
617 kfree(newkey); 604 kfree(newkey);
605 if (tp->md5sig_info->entries6 == 0)
606 tcp_free_md5sig_pool();
618 return -ENOMEM; 607 return -ENOMEM;
619 } 608 }
620 609
@@ -660,6 +649,7 @@ static int tcp_v6_md5_do_del(struct sock *sk, const struct in6_addr *peer)
660 kfree(tp->md5sig_info->keys6); 649 kfree(tp->md5sig_info->keys6);
661 tp->md5sig_info->keys6 = NULL; 650 tp->md5sig_info->keys6 = NULL;
662 tp->md5sig_info->alloced6 = 0; 651 tp->md5sig_info->alloced6 = 0;
652 tcp_free_md5sig_pool();
663 } else { 653 } else {
664 /* shrink the database */ 654 /* shrink the database */
665 if (tp->md5sig_info->entries6 != i) 655 if (tp->md5sig_info->entries6 != i)
@@ -668,7 +658,6 @@ static int tcp_v6_md5_do_del(struct sock *sk, const struct in6_addr *peer)
668 (tp->md5sig_info->entries6 - i) 658 (tp->md5sig_info->entries6 - i)
669 * sizeof (tp->md5sig_info->keys6[0])); 659 * sizeof (tp->md5sig_info->keys6[0]));
670 } 660 }
671 tcp_free_md5sig_pool();
672 return 0; 661 return 0;
673 } 662 }
674 } 663 }
@@ -1093,7 +1082,7 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb)
1093 1082
1094#ifdef CONFIG_TCP_MD5SIG 1083#ifdef CONFIG_TCP_MD5SIG
1095 if (sk) 1084 if (sk)
1096 key = tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr); 1085 key = tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->saddr);
1097#endif 1086#endif
1098 1087
1099 if (th->ack) 1088 if (th->ack)
@@ -1178,11 +1167,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1178 struct tcp_sock *tp = tcp_sk(sk); 1167 struct tcp_sock *tp = tcp_sk(sk);
1179 __u32 isn = TCP_SKB_CB(skb)->when; 1168 __u32 isn = TCP_SKB_CB(skb)->when;
1180 struct dst_entry *dst = NULL; 1169 struct dst_entry *dst = NULL;
1181#ifdef CONFIG_SYN_COOKIES
1182 int want_cookie = 0; 1170 int want_cookie = 0;
1183#else
1184#define want_cookie 0
1185#endif
1186 1171
1187 if (skb->protocol == htons(ETH_P_IP)) 1172 if (skb->protocol == htons(ETH_P_IP))
1188 return tcp_v4_conn_request(sk, skb); 1173 return tcp_v4_conn_request(sk, skb);
@@ -1191,14 +1176,9 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1191 goto drop; 1176 goto drop;
1192 1177
1193 if (inet_csk_reqsk_queue_is_full(sk) && !isn) { 1178 if (inet_csk_reqsk_queue_is_full(sk) && !isn) {
1194 if (net_ratelimit()) 1179 want_cookie = tcp_syn_flood_action(sk, skb, "TCPv6");
1195 syn_flood_warning(skb); 1180 if (!want_cookie)
1196#ifdef CONFIG_SYN_COOKIES 1181 goto drop;
1197 if (sysctl_tcp_syncookies)
1198 want_cookie = 1;
1199 else
1200#endif
1201 goto drop;
1202 } 1182 }
1203 1183
1204 if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) 1184 if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1)
@@ -1248,9 +1228,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1248 while (l-- > 0) 1228 while (l-- > 0)
1249 *c++ ^= *hash_location++; 1229 *c++ ^= *hash_location++;
1250 1230
1251#ifdef CONFIG_SYN_COOKIES
1252 want_cookie = 0; /* not our kind of cookie */ 1231 want_cookie = 0; /* not our kind of cookie */
1253#endif
1254 tmp_ext.cookie_out_never = 0; /* false */ 1232 tmp_ext.cookie_out_never = 0; /* false */
1255 tmp_ext.cookie_plus = tmp_opt.cookie_plus; 1233 tmp_ext.cookie_plus = tmp_opt.cookie_plus;
1256 } else if (!tp->rx_opt.cookie_in_always) { 1234 } else if (!tp->rx_opt.cookie_in_always) {
@@ -1341,6 +1319,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1341 } 1319 }
1342have_isn: 1320have_isn:
1343 tcp_rsk(req)->snt_isn = isn; 1321 tcp_rsk(req)->snt_isn = isn;
1322 tcp_rsk(req)->snt_synack = tcp_time_stamp;
1344 1323
1345 security_inet_conn_request(sk, skb, req); 1324 security_inet_conn_request(sk, skb, req);
1346 1325
@@ -1406,6 +1385,8 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1406 newtp->af_specific = &tcp_sock_ipv6_mapped_specific; 1385 newtp->af_specific = &tcp_sock_ipv6_mapped_specific;
1407#endif 1386#endif
1408 1387
1388 newnp->ipv6_ac_list = NULL;
1389 newnp->ipv6_fl_list = NULL;
1409 newnp->pktoptions = NULL; 1390 newnp->pktoptions = NULL;
1410 newnp->opt = NULL; 1391 newnp->opt = NULL;
1411 newnp->mcast_oif = inet6_iif(skb); 1392 newnp->mcast_oif = inet6_iif(skb);
@@ -1470,6 +1451,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1470 First: no IPv4 options. 1451 First: no IPv4 options.
1471 */ 1452 */
1472 newinet->inet_opt = NULL; 1453 newinet->inet_opt = NULL;
1454 newnp->ipv6_ac_list = NULL;
1473 newnp->ipv6_fl_list = NULL; 1455 newnp->ipv6_fl_list = NULL;
1474 1456
1475 /* Clone RX bits */ 1457 /* Clone RX bits */
@@ -1509,6 +1491,10 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1509 tcp_sync_mss(newsk, dst_mtu(dst)); 1491 tcp_sync_mss(newsk, dst_mtu(dst));
1510 newtp->advmss = dst_metric_advmss(dst); 1492 newtp->advmss = dst_metric_advmss(dst);
1511 tcp_initialize_rcv_mss(newsk); 1493 tcp_initialize_rcv_mss(newsk);
1494 if (tcp_rsk(req)->snt_synack)
1495 tcp_valid_rtt_meas(newsk,
1496 tcp_time_stamp - tcp_rsk(req)->snt_synack);
1497 newtp->total_retrans = req->retrans;
1512 1498
1513 newinet->inet_daddr = newinet->inet_saddr = LOOPBACK4_IPV6; 1499 newinet->inet_daddr = newinet->inet_saddr = LOOPBACK4_IPV6;
1514 newinet->inet_rcv_saddr = LOOPBACK4_IPV6; 1500 newinet->inet_rcv_saddr = LOOPBACK4_IPV6;