diff options
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 42 |
1 files changed, 22 insertions, 20 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 9b6dbba80d31..bd5ef7b6e48e 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 | ||
76 | static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); | 77 | static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); |
78 | static void __tcp_v6_send_check(struct sk_buff *skb, | ||
79 | struct in6_addr *saddr, | ||
80 | struct in6_addr *daddr); | ||
77 | 81 | ||
78 | static const struct inet_connection_sock_af_ops ipv6_mapped; | 82 | static const struct inet_connection_sock_af_ops ipv6_mapped; |
79 | static const struct inet_connection_sock_af_ops ipv6_specific; | 83 | static const struct inet_connection_sock_af_ops ipv6_specific; |
@@ -502,14 +506,10 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req, | |||
502 | 506 | ||
503 | skb = tcp_make_synack(sk, dst, req, rvp); | 507 | skb = tcp_make_synack(sk, dst, req, rvp); |
504 | if (skb) { | 508 | if (skb) { |
505 | struct tcphdr *th = tcp_hdr(skb); | 509 | __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 | 510 | ||
511 | ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr); | 511 | ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr); |
512 | err = ip6_xmit(sk, skb, &fl, opt, 0); | 512 | err = ip6_xmit(sk, skb, &fl, opt); |
513 | err = net_xmit_eval(err); | 513 | err = net_xmit_eval(err); |
514 | } | 514 | } |
515 | 515 | ||
@@ -917,22 +917,29 @@ static struct timewait_sock_ops tcp6_timewait_sock_ops = { | |||
917 | .twsk_destructor= tcp_twsk_destructor, | 917 | .twsk_destructor= tcp_twsk_destructor, |
918 | }; | 918 | }; |
919 | 919 | ||
920 | static void tcp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb) | 920 | static void __tcp_v6_send_check(struct sk_buff *skb, |
921 | struct in6_addr *saddr, struct in6_addr *daddr) | ||
921 | { | 922 | { |
922 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
923 | struct tcphdr *th = tcp_hdr(skb); | 923 | struct tcphdr *th = tcp_hdr(skb); |
924 | 924 | ||
925 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | 925 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
926 | th->check = ~csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP, 0); | 926 | th->check = ~tcp_v6_check(skb->len, saddr, daddr, 0); |
927 | skb->csum_start = skb_transport_header(skb) - skb->head; | 927 | skb->csum_start = skb_transport_header(skb) - skb->head; |
928 | skb->csum_offset = offsetof(struct tcphdr, check); | 928 | skb->csum_offset = offsetof(struct tcphdr, check); |
929 | } else { | 929 | } else { |
930 | th->check = csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP, | 930 | th->check = tcp_v6_check(skb->len, saddr, daddr, |
931 | csum_partial(th, th->doff<<2, | 931 | csum_partial(th, th->doff << 2, |
932 | skb->csum)); | 932 | skb->csum)); |
933 | } | 933 | } |
934 | } | 934 | } |
935 | 935 | ||
936 | static void tcp_v6_send_check(struct sock *sk, struct sk_buff *skb) | ||
937 | { | ||
938 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
939 | |||
940 | __tcp_v6_send_check(skb, &np->saddr, &np->daddr); | ||
941 | } | ||
942 | |||
936 | static int tcp_v6_gso_send_check(struct sk_buff *skb) | 943 | static int tcp_v6_gso_send_check(struct sk_buff *skb) |
937 | { | 944 | { |
938 | struct ipv6hdr *ipv6h; | 945 | struct ipv6hdr *ipv6h; |
@@ -945,11 +952,8 @@ static int tcp_v6_gso_send_check(struct sk_buff *skb) | |||
945 | th = tcp_hdr(skb); | 952 | th = tcp_hdr(skb); |
946 | 953 | ||
947 | th->check = 0; | 954 | th->check = 0; |
948 | th->check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr, skb->len, | ||
949 | IPPROTO_TCP, 0); | ||
950 | skb->csum_start = skb_transport_header(skb) - skb->head; | ||
951 | skb->csum_offset = offsetof(struct tcphdr, check); | ||
952 | skb->ip_summed = CHECKSUM_PARTIAL; | 955 | skb->ip_summed = CHECKSUM_PARTIAL; |
956 | __tcp_v6_send_check(skb, &ipv6h->saddr, &ipv6h->daddr); | ||
953 | return 0; | 957 | return 0; |
954 | } | 958 | } |
955 | 959 | ||
@@ -1052,9 +1056,7 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, | |||
1052 | ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr); | 1056 | ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr); |
1053 | ipv6_addr_copy(&fl.fl6_src, &ipv6_hdr(skb)->daddr); | 1057 | ipv6_addr_copy(&fl.fl6_src, &ipv6_hdr(skb)->daddr); |
1054 | 1058 | ||
1055 | t1->check = csum_ipv6_magic(&fl.fl6_src, &fl.fl6_dst, | 1059 | __tcp_v6_send_check(buff, &fl.fl6_src, &fl.fl6_dst); |
1056 | tot_len, IPPROTO_TCP, | ||
1057 | buff->csum); | ||
1058 | 1060 | ||
1059 | fl.proto = IPPROTO_TCP; | 1061 | fl.proto = IPPROTO_TCP; |
1060 | fl.oif = inet6_iif(skb); | 1062 | fl.oif = inet6_iif(skb); |
@@ -1069,7 +1071,7 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, | |||
1069 | if (!ip6_dst_lookup(ctl_sk, &dst, &fl)) { | 1071 | if (!ip6_dst_lookup(ctl_sk, &dst, &fl)) { |
1070 | if (xfrm_lookup(net, &dst, &fl, NULL, 0) >= 0) { | 1072 | if (xfrm_lookup(net, &dst, &fl, NULL, 0) >= 0) { |
1071 | skb_dst_set(buff, dst); | 1073 | skb_dst_set(buff, dst); |
1072 | ip6_xmit(ctl_sk, buff, &fl, NULL, 0); | 1074 | ip6_xmit(ctl_sk, buff, &fl, NULL); |
1073 | TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS); | 1075 | TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS); |
1074 | if (rst) | 1076 | if (rst) |
1075 | TCP_INC_STATS_BH(net, TCP_MIB_OUTRSTS); | 1077 | TCP_INC_STATS_BH(net, TCP_MIB_OUTRSTS); |