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.c147
1 files changed, 81 insertions, 66 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index febfd595a40d..fe6d40418c0b 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -38,6 +38,7 @@
38#include <linux/jhash.h> 38#include <linux/jhash.h>
39#include <linux/ipsec.h> 39#include <linux/ipsec.h>
40#include <linux/times.h> 40#include <linux/times.h>
41#include <linux/slab.h>
41 42
42#include <linux/ipv6.h> 43#include <linux/ipv6.h>
43#include <linux/icmpv6.h> 44#include <linux/icmpv6.h>
@@ -74,6 +75,9 @@ static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
74 struct request_sock *req); 75 struct request_sock *req);
75 76
76static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); 77static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb);
78static void __tcp_v6_send_check(struct sk_buff *skb,
79 struct in6_addr *saddr,
80 struct in6_addr *daddr);
77 81
78static const struct inet_connection_sock_af_ops ipv6_mapped; 82static const struct inet_connection_sock_af_ops ipv6_mapped;
79static const struct inet_connection_sock_af_ops ipv6_specific; 83static const struct inet_connection_sock_af_ops ipv6_specific;
@@ -125,7 +129,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
125 struct inet_connection_sock *icsk = inet_csk(sk); 129 struct inet_connection_sock *icsk = inet_csk(sk);
126 struct ipv6_pinfo *np = inet6_sk(sk); 130 struct ipv6_pinfo *np = inet6_sk(sk);
127 struct tcp_sock *tp = tcp_sk(sk); 131 struct tcp_sock *tp = tcp_sk(sk);
128 struct in6_addr *saddr = NULL, *final_p = NULL, final; 132 struct in6_addr *saddr = NULL, *final_p, final;
129 struct flowi fl; 133 struct flowi fl;
130 struct dst_entry *dst; 134 struct dst_entry *dst;
131 int addr_type; 135 int addr_type;
@@ -246,12 +250,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
246 fl.fl_ip_dport = usin->sin6_port; 250 fl.fl_ip_dport = usin->sin6_port;
247 fl.fl_ip_sport = inet->inet_sport; 251 fl.fl_ip_sport = inet->inet_sport;
248 252
249 if (np->opt && np->opt->srcrt) { 253 final_p = fl6_update_dst(&fl, np->opt, &final);
250 struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt;
251 ipv6_addr_copy(&final, &fl.fl6_dst);
252 ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
253 final_p = &final;
254 }
255 254
256 security_sk_classify_flow(sk, &fl); 255 security_sk_classify_flow(sk, &fl);
257 256
@@ -349,6 +348,11 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
349 if (sk->sk_state == TCP_CLOSE) 348 if (sk->sk_state == TCP_CLOSE)
350 goto out; 349 goto out;
351 350
351 if (ipv6_hdr(skb)->hop_limit < inet6_sk(sk)->min_hopcount) {
352 NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP);
353 goto out;
354 }
355
352 tp = tcp_sk(sk); 356 tp = tcp_sk(sk);
353 seq = ntohl(th->seq); 357 seq = ntohl(th->seq);
354 if (sk->sk_state != TCP_LISTEN && 358 if (sk->sk_state != TCP_LISTEN &&
@@ -468,7 +472,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
468 struct ipv6_pinfo *np = inet6_sk(sk); 472 struct ipv6_pinfo *np = inet6_sk(sk);
469 struct sk_buff * skb; 473 struct sk_buff * skb;
470 struct ipv6_txoptions *opt = NULL; 474 struct ipv6_txoptions *opt = NULL;
471 struct in6_addr * final_p = NULL, final; 475 struct in6_addr * final_p, final;
472 struct flowi fl; 476 struct flowi fl;
473 struct dst_entry *dst; 477 struct dst_entry *dst;
474 int err = -1; 478 int err = -1;
@@ -485,12 +489,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
485 security_req_classify_flow(req, &fl); 489 security_req_classify_flow(req, &fl);
486 490
487 opt = np->opt; 491 opt = np->opt;
488 if (opt && opt->srcrt) { 492 final_p = fl6_update_dst(&fl, opt, &final);
489 struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
490 ipv6_addr_copy(&final, &fl.fl6_dst);
491 ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
492 final_p = &final;
493 }
494 493
495 err = ip6_dst_lookup(sk, &dst, &fl); 494 err = ip6_dst_lookup(sk, &dst, &fl);
496 if (err) 495 if (err)
@@ -502,14 +501,10 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
502 501
503 skb = tcp_make_synack(sk, dst, req, rvp); 502 skb = tcp_make_synack(sk, dst, req, rvp);
504 if (skb) { 503 if (skb) {
505 struct tcphdr *th = tcp_hdr(skb); 504 __tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr);
506
507 th->check = tcp_v6_check(skb->len,
508 &treq->loc_addr, &treq->rmt_addr,
509 csum_partial(th, skb->len, skb->csum));
510 505
511 ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr); 506 ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr);
512 err = ip6_xmit(sk, skb, &fl, opt, 0); 507 err = ip6_xmit(sk, skb, &fl, opt);
513 err = net_xmit_eval(err); 508 err = net_xmit_eval(err);
514 } 509 }
515 510
@@ -520,6 +515,13 @@ done:
520 return err; 515 return err;
521} 516}
522 517
518static int tcp_v6_rtx_synack(struct sock *sk, struct request_sock *req,
519 struct request_values *rvp)
520{
521 TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS);
522 return tcp_v6_send_synack(sk, req, rvp);
523}
524
523static inline void syn_flood_warning(struct sk_buff *skb) 525static inline void syn_flood_warning(struct sk_buff *skb)
524{ 526{
525#ifdef CONFIG_SYN_COOKIES 527#ifdef CONFIG_SYN_COOKIES
@@ -592,7 +594,7 @@ static int tcp_v6_md5_do_add(struct sock *sk, struct in6_addr *peer,
592 kfree(newkey); 594 kfree(newkey);
593 return -ENOMEM; 595 return -ENOMEM;
594 } 596 }
595 sk->sk_route_caps &= ~NETIF_F_GSO_MASK; 597 sk_nocaps_add(sk, NETIF_F_GSO_MASK);
596 } 598 }
597 if (tcp_alloc_md5sig_pool(sk) == NULL) { 599 if (tcp_alloc_md5sig_pool(sk) == NULL) {
598 kfree(newkey); 600 kfree(newkey);
@@ -729,7 +731,7 @@ static int tcp_v6_parse_md5_keys (struct sock *sk, char __user *optval,
729 return -ENOMEM; 731 return -ENOMEM;
730 732
731 tp->md5sig_info = p; 733 tp->md5sig_info = p;
732 sk->sk_route_caps &= ~NETIF_F_GSO_MASK; 734 sk_nocaps_add(sk, NETIF_F_GSO_MASK);
733 } 735 }
734 736
735 newkey = kmemdup(cmd.tcpm_key, cmd.tcpm_keylen, GFP_KERNEL); 737 newkey = kmemdup(cmd.tcpm_key, cmd.tcpm_keylen, GFP_KERNEL);
@@ -876,7 +878,7 @@ static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb)
876 878
877 if (genhash || memcmp(hash_location, newhash, 16) != 0) { 879 if (genhash || memcmp(hash_location, newhash, 16) != 0) {
878 if (net_ratelimit()) { 880 if (net_ratelimit()) {
879 printk(KERN_INFO "MD5 Hash %s for (%pI6, %u)->(%pI6, %u)\n", 881 printk(KERN_INFO "MD5 Hash %s for [%pI6c]:%u->[%pI6c]:%u\n",
880 genhash ? "failed" : "mismatch", 882 genhash ? "failed" : "mismatch",
881 &ip6h->saddr, ntohs(th->source), 883 &ip6h->saddr, ntohs(th->source),
882 &ip6h->daddr, ntohs(th->dest)); 884 &ip6h->daddr, ntohs(th->dest));
@@ -890,10 +892,11 @@ static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb)
890struct request_sock_ops tcp6_request_sock_ops __read_mostly = { 892struct request_sock_ops tcp6_request_sock_ops __read_mostly = {
891 .family = AF_INET6, 893 .family = AF_INET6,
892 .obj_size = sizeof(struct tcp6_request_sock), 894 .obj_size = sizeof(struct tcp6_request_sock),
893 .rtx_syn_ack = tcp_v6_send_synack, 895 .rtx_syn_ack = tcp_v6_rtx_synack,
894 .send_ack = tcp_v6_reqsk_send_ack, 896 .send_ack = tcp_v6_reqsk_send_ack,
895 .destructor = tcp_v6_reqsk_destructor, 897 .destructor = tcp_v6_reqsk_destructor,
896 .send_reset = tcp_v6_send_reset 898 .send_reset = tcp_v6_send_reset,
899 .syn_ack_timeout = tcp_syn_ack_timeout,
897}; 900};
898 901
899#ifdef CONFIG_TCP_MD5SIG 902#ifdef CONFIG_TCP_MD5SIG
@@ -909,22 +912,29 @@ static struct timewait_sock_ops tcp6_timewait_sock_ops = {
909 .twsk_destructor= tcp_twsk_destructor, 912 .twsk_destructor= tcp_twsk_destructor,
910}; 913};
911 914
912static void tcp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb) 915static void __tcp_v6_send_check(struct sk_buff *skb,
916 struct in6_addr *saddr, struct in6_addr *daddr)
913{ 917{
914 struct ipv6_pinfo *np = inet6_sk(sk);
915 struct tcphdr *th = tcp_hdr(skb); 918 struct tcphdr *th = tcp_hdr(skb);
916 919
917 if (skb->ip_summed == CHECKSUM_PARTIAL) { 920 if (skb->ip_summed == CHECKSUM_PARTIAL) {
918 th->check = ~csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP, 0); 921 th->check = ~tcp_v6_check(skb->len, saddr, daddr, 0);
919 skb->csum_start = skb_transport_header(skb) - skb->head; 922 skb->csum_start = skb_transport_header(skb) - skb->head;
920 skb->csum_offset = offsetof(struct tcphdr, check); 923 skb->csum_offset = offsetof(struct tcphdr, check);
921 } else { 924 } else {
922 th->check = csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP, 925 th->check = tcp_v6_check(skb->len, saddr, daddr,
923 csum_partial(th, th->doff<<2, 926 csum_partial(th, th->doff << 2,
924 skb->csum)); 927 skb->csum));
925 } 928 }
926} 929}
927 930
931static void tcp_v6_send_check(struct sock *sk, struct sk_buff *skb)
932{
933 struct ipv6_pinfo *np = inet6_sk(sk);
934
935 __tcp_v6_send_check(skb, &np->saddr, &np->daddr);
936}
937
928static int tcp_v6_gso_send_check(struct sk_buff *skb) 938static int tcp_v6_gso_send_check(struct sk_buff *skb)
929{ 939{
930 struct ipv6hdr *ipv6h; 940 struct ipv6hdr *ipv6h;
@@ -937,11 +947,8 @@ static int tcp_v6_gso_send_check(struct sk_buff *skb)
937 th = tcp_hdr(skb); 947 th = tcp_hdr(skb);
938 948
939 th->check = 0; 949 th->check = 0;
940 th->check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr, skb->len,
941 IPPROTO_TCP, 0);
942 skb->csum_start = skb_transport_header(skb) - skb->head;
943 skb->csum_offset = offsetof(struct tcphdr, check);
944 skb->ip_summed = CHECKSUM_PARTIAL; 950 skb->ip_summed = CHECKSUM_PARTIAL;
951 __tcp_v6_send_check(skb, &ipv6h->saddr, &ipv6h->daddr);
945 return 0; 952 return 0;
946} 953}
947 954
@@ -1006,7 +1013,7 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
1006 skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len); 1013 skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len);
1007 1014
1008 t1 = (struct tcphdr *) skb_push(buff, tot_len); 1015 t1 = (struct tcphdr *) skb_push(buff, tot_len);
1009 skb_reset_transport_header(skb); 1016 skb_reset_transport_header(buff);
1010 1017
1011 /* Swap the send and the receive. */ 1018 /* Swap the send and the receive. */
1012 memset(t1, 0, sizeof(*t1)); 1019 memset(t1, 0, sizeof(*t1));
@@ -1038,15 +1045,14 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
1038 } 1045 }
1039#endif 1046#endif
1040 1047
1041 buff->csum = csum_partial(t1, tot_len, 0);
1042
1043 memset(&fl, 0, sizeof(fl)); 1048 memset(&fl, 0, sizeof(fl));
1044 ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr); 1049 ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr);
1045 ipv6_addr_copy(&fl.fl6_src, &ipv6_hdr(skb)->daddr); 1050 ipv6_addr_copy(&fl.fl6_src, &ipv6_hdr(skb)->daddr);
1046 1051
1047 t1->check = csum_ipv6_magic(&fl.fl6_src, &fl.fl6_dst, 1052 buff->ip_summed = CHECKSUM_PARTIAL;
1048 tot_len, IPPROTO_TCP, 1053 buff->csum = 0;
1049 buff->csum); 1054
1055 __tcp_v6_send_check(buff, &fl.fl6_src, &fl.fl6_dst);
1050 1056
1051 fl.proto = IPPROTO_TCP; 1057 fl.proto = IPPROTO_TCP;
1052 fl.oif = inet6_iif(skb); 1058 fl.oif = inet6_iif(skb);
@@ -1061,7 +1067,7 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
1061 if (!ip6_dst_lookup(ctl_sk, &dst, &fl)) { 1067 if (!ip6_dst_lookup(ctl_sk, &dst, &fl)) {
1062 if (xfrm_lookup(net, &dst, &fl, NULL, 0) >= 0) { 1068 if (xfrm_lookup(net, &dst, &fl, NULL, 0) >= 0) {
1063 skb_dst_set(buff, dst); 1069 skb_dst_set(buff, dst);
1064 ip6_xmit(ctl_sk, buff, &fl, NULL, 0); 1070 ip6_xmit(ctl_sk, buff, &fl, NULL);
1065 TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS); 1071 TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS);
1066 if (rst) 1072 if (rst)
1067 TCP_INC_STATS_BH(net, TCP_MIB_OUTRSTS); 1073 TCP_INC_STATS_BH(net, TCP_MIB_OUTRSTS);
@@ -1151,7 +1157,7 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
1151 } 1157 }
1152 1158
1153#ifdef CONFIG_SYN_COOKIES 1159#ifdef CONFIG_SYN_COOKIES
1154 if (!th->rst && !th->syn && th->ack) 1160 if (!th->syn)
1155 sk = cookie_v6_check(sk, skb); 1161 sk = cookie_v6_check(sk, skb);
1156#endif 1162#endif
1157 return sk; 1163 return sk;
@@ -1224,12 +1230,12 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1224 goto drop_and_free; 1230 goto drop_and_free;
1225 1231
1226 /* Secret recipe starts with IP addresses */ 1232 /* Secret recipe starts with IP addresses */
1227 d = &ipv6_hdr(skb)->daddr.s6_addr32[0]; 1233 d = (__force u32 *)&ipv6_hdr(skb)->daddr.s6_addr32[0];
1228 *mess++ ^= *d++; 1234 *mess++ ^= *d++;
1229 *mess++ ^= *d++; 1235 *mess++ ^= *d++;
1230 *mess++ ^= *d++; 1236 *mess++ ^= *d++;
1231 *mess++ ^= *d++; 1237 *mess++ ^= *d++;
1232 d = &ipv6_hdr(skb)->saddr.s6_addr32[0]; 1238 d = (__force u32 *)&ipv6_hdr(skb)->saddr.s6_addr32[0];
1233 *mess++ ^= *d++; 1239 *mess++ ^= *d++;
1234 *mess++ ^= *d++; 1240 *mess++ ^= *d++;
1235 *mess++ ^= *d++; 1241 *mess++ ^= *d++;
@@ -1263,13 +1269,10 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1263 treq = inet6_rsk(req); 1269 treq = inet6_rsk(req);
1264 ipv6_addr_copy(&treq->rmt_addr, &ipv6_hdr(skb)->saddr); 1270 ipv6_addr_copy(&treq->rmt_addr, &ipv6_hdr(skb)->saddr);
1265 ipv6_addr_copy(&treq->loc_addr, &ipv6_hdr(skb)->daddr); 1271 ipv6_addr_copy(&treq->loc_addr, &ipv6_hdr(skb)->daddr);
1266 if (!want_cookie) 1272 if (!want_cookie || tmp_opt.tstamp_ok)
1267 TCP_ECN_create_request(req, tcp_hdr(skb)); 1273 TCP_ECN_create_request(req, tcp_hdr(skb));
1268 1274
1269 if (want_cookie) { 1275 if (!isn) {
1270 isn = cookie_v6_init_sequence(sk, skb, &req->mss);
1271 req->cookie_ts = tmp_opt.tstamp_ok;
1272 } else if (!isn) {
1273 if (ipv6_opt_accepted(sk, skb) || 1276 if (ipv6_opt_accepted(sk, skb) ||
1274 np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo || 1277 np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo ||
1275 np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) { 1278 np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) {
@@ -1282,8 +1285,12 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1282 if (!sk->sk_bound_dev_if && 1285 if (!sk->sk_bound_dev_if &&
1283 ipv6_addr_type(&treq->rmt_addr) & IPV6_ADDR_LINKLOCAL) 1286 ipv6_addr_type(&treq->rmt_addr) & IPV6_ADDR_LINKLOCAL)
1284 treq->iif = inet6_iif(skb); 1287 treq->iif = inet6_iif(skb);
1285 1288 if (!want_cookie) {
1286 isn = tcp_v6_init_sequence(skb); 1289 isn = tcp_v6_init_sequence(skb);
1290 } else {
1291 isn = cookie_v6_init_sequence(sk, skb, &req->mss);
1292 req->cookie_ts = tmp_opt.tstamp_ok;
1293 }
1287 } 1294 }
1288 tcp_rsk(req)->snt_isn = isn; 1295 tcp_rsk(req)->snt_isn = isn;
1289 1296
@@ -1376,18 +1383,13 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1376 goto out_overflow; 1383 goto out_overflow;
1377 1384
1378 if (dst == NULL) { 1385 if (dst == NULL) {
1379 struct in6_addr *final_p = NULL, final; 1386 struct in6_addr *final_p, final;
1380 struct flowi fl; 1387 struct flowi fl;
1381 1388
1382 memset(&fl, 0, sizeof(fl)); 1389 memset(&fl, 0, sizeof(fl));
1383 fl.proto = IPPROTO_TCP; 1390 fl.proto = IPPROTO_TCP;
1384 ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr); 1391 ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr);
1385 if (opt && opt->srcrt) { 1392 final_p = fl6_update_dst(&fl, opt, &final);
1386 struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
1387 ipv6_addr_copy(&final, &fl.fl6_dst);
1388 ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
1389 final_p = &final;
1390 }
1391 ipv6_addr_copy(&fl.fl6_src, &treq->loc_addr); 1393 ipv6_addr_copy(&fl.fl6_src, &treq->loc_addr);
1392 fl.oif = sk->sk_bound_dev_if; 1394 fl.oif = sk->sk_bound_dev_if;
1393 fl.mark = sk->sk_mark; 1395 fl.mark = sk->sk_mark;
@@ -1667,6 +1669,7 @@ ipv6_pktoptions:
1667static int tcp_v6_rcv(struct sk_buff *skb) 1669static int tcp_v6_rcv(struct sk_buff *skb)
1668{ 1670{
1669 struct tcphdr *th; 1671 struct tcphdr *th;
1672 struct ipv6hdr *hdr;
1670 struct sock *sk; 1673 struct sock *sk;
1671 int ret; 1674 int ret;
1672 struct net *net = dev_net(skb->dev); 1675 struct net *net = dev_net(skb->dev);
@@ -1693,12 +1696,13 @@ static int tcp_v6_rcv(struct sk_buff *skb)
1693 goto bad_packet; 1696 goto bad_packet;
1694 1697
1695 th = tcp_hdr(skb); 1698 th = tcp_hdr(skb);
1699 hdr = ipv6_hdr(skb);
1696 TCP_SKB_CB(skb)->seq = ntohl(th->seq); 1700 TCP_SKB_CB(skb)->seq = ntohl(th->seq);
1697 TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + 1701 TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin +
1698 skb->len - th->doff*4); 1702 skb->len - th->doff*4);
1699 TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); 1703 TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq);
1700 TCP_SKB_CB(skb)->when = 0; 1704 TCP_SKB_CB(skb)->when = 0;
1701 TCP_SKB_CB(skb)->flags = ipv6_get_dsfield(ipv6_hdr(skb)); 1705 TCP_SKB_CB(skb)->flags = ipv6_get_dsfield(hdr);
1702 TCP_SKB_CB(skb)->sacked = 0; 1706 TCP_SKB_CB(skb)->sacked = 0;
1703 1707
1704 sk = __inet6_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest); 1708 sk = __inet6_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest);
@@ -1709,6 +1713,11 @@ process:
1709 if (sk->sk_state == TCP_TIME_WAIT) 1713 if (sk->sk_state == TCP_TIME_WAIT)
1710 goto do_time_wait; 1714 goto do_time_wait;
1711 1715
1716 if (hdr->hop_limit < inet6_sk(sk)->min_hopcount) {
1717 NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP);
1718 goto discard_and_relse;
1719 }
1720
1712 if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) 1721 if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
1713 goto discard_and_relse; 1722 goto discard_and_relse;
1714 1723
@@ -1732,8 +1741,11 @@ process:
1732 if (!tcp_prequeue(sk, skb)) 1741 if (!tcp_prequeue(sk, skb))
1733 ret = tcp_v6_do_rcv(sk, skb); 1742 ret = tcp_v6_do_rcv(sk, skb);
1734 } 1743 }
1735 } else 1744 } else if (unlikely(sk_add_backlog(sk, skb))) {
1736 sk_add_backlog(sk, skb); 1745 bh_unlock_sock(sk);
1746 NET_INC_STATS_BH(net, LINUX_MIB_TCPBACKLOGDROP);
1747 goto discard_and_relse;
1748 }
1737 bh_unlock_sock(sk); 1749 bh_unlock_sock(sk);
1738 1750
1739 sock_put(sk); 1751 sock_put(sk);
@@ -2105,7 +2117,7 @@ static struct tcp_seq_afinfo tcp6_seq_afinfo = {
2105 }, 2117 },
2106}; 2118};
2107 2119
2108int tcp6_proc_init(struct net *net) 2120int __net_init tcp6_proc_init(struct net *net)
2109{ 2121{
2110 return tcp_proc_register(net, &tcp6_seq_afinfo); 2122 return tcp_proc_register(net, &tcp6_seq_afinfo);
2111} 2123}
@@ -2130,6 +2142,8 @@ struct proto tcpv6_prot = {
2130 .setsockopt = tcp_setsockopt, 2142 .setsockopt = tcp_setsockopt,
2131 .getsockopt = tcp_getsockopt, 2143 .getsockopt = tcp_getsockopt,
2132 .recvmsg = tcp_recvmsg, 2144 .recvmsg = tcp_recvmsg,
2145 .sendmsg = tcp_sendmsg,
2146 .sendpage = tcp_sendpage,
2133 .backlog_rcv = tcp_v6_do_rcv, 2147 .backlog_rcv = tcp_v6_do_rcv,
2134 .hash = tcp_v6_hash, 2148 .hash = tcp_v6_hash,
2135 .unhash = inet_unhash, 2149 .unhash = inet_unhash,
@@ -2148,6 +2162,7 @@ struct proto tcpv6_prot = {
2148 .twsk_prot = &tcp6_timewait_sock_ops, 2162 .twsk_prot = &tcp6_timewait_sock_ops,
2149 .rsk_prot = &tcp6_request_sock_ops, 2163 .rsk_prot = &tcp6_request_sock_ops,
2150 .h.hashinfo = &tcp_hashinfo, 2164 .h.hashinfo = &tcp_hashinfo,
2165 .no_autobind = true,
2151#ifdef CONFIG_COMPAT 2166#ifdef CONFIG_COMPAT
2152 .compat_setsockopt = compat_tcp_setsockopt, 2167 .compat_setsockopt = compat_tcp_setsockopt,
2153 .compat_getsockopt = compat_tcp_getsockopt, 2168 .compat_getsockopt = compat_tcp_getsockopt,
@@ -2174,18 +2189,18 @@ static struct inet_protosw tcpv6_protosw = {
2174 INET_PROTOSW_ICSK, 2189 INET_PROTOSW_ICSK,
2175}; 2190};
2176 2191
2177static int tcpv6_net_init(struct net *net) 2192static int __net_init tcpv6_net_init(struct net *net)
2178{ 2193{
2179 return inet_ctl_sock_create(&net->ipv6.tcp_sk, PF_INET6, 2194 return inet_ctl_sock_create(&net->ipv6.tcp_sk, PF_INET6,
2180 SOCK_RAW, IPPROTO_TCP, net); 2195 SOCK_RAW, IPPROTO_TCP, net);
2181} 2196}
2182 2197
2183static void tcpv6_net_exit(struct net *net) 2198static void __net_exit tcpv6_net_exit(struct net *net)
2184{ 2199{
2185 inet_ctl_sock_destroy(net->ipv6.tcp_sk); 2200 inet_ctl_sock_destroy(net->ipv6.tcp_sk);
2186} 2201}
2187 2202
2188static void tcpv6_net_exit_batch(struct list_head *net_exit_list) 2203static void __net_exit tcpv6_net_exit_batch(struct list_head *net_exit_list)
2189{ 2204{
2190 inet_twsk_purge(&tcp_hashinfo, &tcp_death_row, AF_INET6); 2205 inet_twsk_purge(&tcp_hashinfo, &tcp_death_row, AF_INET6);
2191} 2206}