diff options
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 50 |
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 | ||
533 | static 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 | |||
547 | static void tcp_v6_reqsk_destructor(struct request_sock *req) | 534 | static 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 | } |
1342 | have_isn: | 1320 | have_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; |