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.c166
1 files changed, 50 insertions, 116 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index b585c850a89a..e5310c9b84dc 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -330,7 +330,8 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
330 th->dest, &hdr->saddr, th->source, skb->dev->ifindex); 330 th->dest, &hdr->saddr, th->source, skb->dev->ifindex);
331 331
332 if (sk == NULL) { 332 if (sk == NULL) {
333 ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS); 333 ICMP6_INC_STATS_BH(net, __in6_dev_get(skb->dev),
334 ICMP6_MIB_INERRORS);
334 return; 335 return;
335 } 336 }
336 337
@@ -941,117 +942,14 @@ static int tcp_v6_gso_send_check(struct sk_buff *skb)
941 return 0; 942 return 0;
942} 943}
943 944
944static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb) 945static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
946 u32 ts, struct tcp_md5sig_key *key, int rst)
945{ 947{
946 struct tcphdr *th = tcp_hdr(skb), *t1; 948 struct tcphdr *th = tcp_hdr(skb), *t1;
947 struct sk_buff *buff; 949 struct sk_buff *buff;
948 struct flowi fl; 950 struct flowi fl;
949 struct net *net = dev_net(skb->dst->dev); 951 struct net *net = dev_net(skb->dst->dev);
950 struct sock *ctl_sk = net->ipv6.tcp_sk; 952 struct sock *ctl_sk = net->ipv6.tcp_sk;
951 unsigned int tot_len = sizeof(*th);
952#ifdef CONFIG_TCP_MD5SIG
953 struct tcp_md5sig_key *key;
954#endif
955
956 if (th->rst)
957 return;
958
959 if (!ipv6_unicast_destination(skb))
960 return;
961
962#ifdef CONFIG_TCP_MD5SIG
963 if (sk)
964 key = tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr);
965 else
966 key = NULL;
967
968 if (key)
969 tot_len += TCPOLEN_MD5SIG_ALIGNED;
970#endif
971
972 /*
973 * We need to grab some memory, and put together an RST,
974 * and then put it into the queue to be sent.
975 */
976
977 buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + tot_len,
978 GFP_ATOMIC);
979 if (buff == NULL)
980 return;
981
982 skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len);
983
984 t1 = (struct tcphdr *) skb_push(buff, tot_len);
985
986 /* Swap the send and the receive. */
987 memset(t1, 0, sizeof(*t1));
988 t1->dest = th->source;
989 t1->source = th->dest;
990 t1->doff = tot_len / 4;
991 t1->rst = 1;
992
993 if(th->ack) {
994 t1->seq = th->ack_seq;
995 } else {
996 t1->ack = 1;
997 t1->ack_seq = htonl(ntohl(th->seq) + th->syn + th->fin
998 + skb->len - (th->doff<<2));
999 }
1000
1001#ifdef CONFIG_TCP_MD5SIG
1002 if (key) {
1003 __be32 *opt = (__be32*)(t1 + 1);
1004 opt[0] = htonl((TCPOPT_NOP << 24) |
1005 (TCPOPT_NOP << 16) |
1006 (TCPOPT_MD5SIG << 8) |
1007 TCPOLEN_MD5SIG);
1008 tcp_v6_md5_hash_hdr((__u8 *)&opt[1], key,
1009 &ipv6_hdr(skb)->daddr,
1010 &ipv6_hdr(skb)->saddr, t1);
1011 }
1012#endif
1013
1014 buff->csum = csum_partial((char *)t1, sizeof(*t1), 0);
1015
1016 memset(&fl, 0, sizeof(fl));
1017 ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr);
1018 ipv6_addr_copy(&fl.fl6_src, &ipv6_hdr(skb)->daddr);
1019
1020 t1->check = csum_ipv6_magic(&fl.fl6_src, &fl.fl6_dst,
1021 sizeof(*t1), IPPROTO_TCP,
1022 buff->csum);
1023
1024 fl.proto = IPPROTO_TCP;
1025 fl.oif = inet6_iif(skb);
1026 fl.fl_ip_dport = t1->dest;
1027 fl.fl_ip_sport = t1->source;
1028 security_skb_classify_flow(skb, &fl);
1029
1030 /* Pass a socket to ip6_dst_lookup either it is for RST
1031 * Underlying function will use this to retrieve the network
1032 * namespace
1033 */
1034 if (!ip6_dst_lookup(ctl_sk, &buff->dst, &fl)) {
1035
1036 if (xfrm_lookup(&buff->dst, &fl, NULL, 0) >= 0) {
1037 ip6_xmit(ctl_sk, buff, &fl, NULL, 0);
1038 TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS);
1039 TCP_INC_STATS_BH(net, TCP_MIB_OUTRSTS);
1040 return;
1041 }
1042 }
1043
1044 kfree_skb(buff);
1045}
1046
1047static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts,
1048 struct tcp_md5sig_key *key)
1049{
1050 struct tcphdr *th = tcp_hdr(skb), *t1;
1051 struct sk_buff *buff;
1052 struct flowi fl;
1053 struct net *net = dev_net(skb->dev);
1054 struct sock *ctl_sk = net->ipv6.tcp_sk;
1055 unsigned int tot_len = sizeof(struct tcphdr); 953 unsigned int tot_len = sizeof(struct tcphdr);
1056 __be32 *topt; 954 __be32 *topt;
1057 955
@@ -1069,16 +967,17 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
1069 967
1070 skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len); 968 skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len);
1071 969
1072 t1 = (struct tcphdr *) skb_push(buff,tot_len); 970 t1 = (struct tcphdr *) skb_push(buff, tot_len);
1073 971
1074 /* Swap the send and the receive. */ 972 /* Swap the send and the receive. */
1075 memset(t1, 0, sizeof(*t1)); 973 memset(t1, 0, sizeof(*t1));
1076 t1->dest = th->source; 974 t1->dest = th->source;
1077 t1->source = th->dest; 975 t1->source = th->dest;
1078 t1->doff = tot_len/4; 976 t1->doff = tot_len / 4;
1079 t1->seq = htonl(seq); 977 t1->seq = htonl(seq);
1080 t1->ack_seq = htonl(ack); 978 t1->ack_seq = htonl(ack);
1081 t1->ack = 1; 979 t1->ack = !rst || !th->ack;
980 t1->rst = rst;
1082 t1->window = htons(win); 981 t1->window = htons(win);
1083 982
1084 topt = (__be32 *)(t1 + 1); 983 topt = (__be32 *)(t1 + 1);
@@ -1087,7 +986,7 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
1087 *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | 986 *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
1088 (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); 987 (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP);
1089 *topt++ = htonl(tcp_time_stamp); 988 *topt++ = htonl(tcp_time_stamp);
1090 *topt = htonl(ts); 989 *topt++ = htonl(ts);
1091 } 990 }
1092 991
1093#ifdef CONFIG_TCP_MD5SIG 992#ifdef CONFIG_TCP_MD5SIG
@@ -1116,10 +1015,16 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
1116 fl.fl_ip_sport = t1->source; 1015 fl.fl_ip_sport = t1->source;
1117 security_skb_classify_flow(skb, &fl); 1016 security_skb_classify_flow(skb, &fl);
1118 1017
1018 /* Pass a socket to ip6_dst_lookup either it is for RST
1019 * Underlying function will use this to retrieve the network
1020 * namespace
1021 */
1119 if (!ip6_dst_lookup(ctl_sk, &buff->dst, &fl)) { 1022 if (!ip6_dst_lookup(ctl_sk, &buff->dst, &fl)) {
1120 if (xfrm_lookup(&buff->dst, &fl, NULL, 0) >= 0) { 1023 if (xfrm_lookup(&buff->dst, &fl, NULL, 0) >= 0) {
1121 ip6_xmit(ctl_sk, buff, &fl, NULL, 0); 1024 ip6_xmit(ctl_sk, buff, &fl, NULL, 0);
1122 TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS); 1025 TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS);
1026 if (rst)
1027 TCP_INC_STATS_BH(net, TCP_MIB_OUTRSTS);
1123 return; 1028 return;
1124 } 1029 }
1125 } 1030 }
@@ -1127,6 +1032,38 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
1127 kfree_skb(buff); 1032 kfree_skb(buff);
1128} 1033}
1129 1034
1035static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb)
1036{
1037 struct tcphdr *th = tcp_hdr(skb);
1038 u32 seq = 0, ack_seq = 0;
1039 struct tcp_md5sig_key *key = NULL;
1040
1041 if (th->rst)
1042 return;
1043
1044 if (!ipv6_unicast_destination(skb))
1045 return;
1046
1047#ifdef CONFIG_TCP_MD5SIG
1048 if (sk)
1049 key = tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr);
1050#endif
1051
1052 if (th->ack)
1053 seq = ntohl(th->ack_seq);
1054 else
1055 ack_seq = ntohl(th->seq) + th->syn + th->fin + skb->len -
1056 (th->doff << 2);
1057
1058 tcp_v6_send_response(skb, seq, ack_seq, 0, 0, key, 1);
1059}
1060
1061static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts,
1062 struct tcp_md5sig_key *key)
1063{
1064 tcp_v6_send_response(skb, seq, ack, win, ts, key, 0);
1065}
1066
1130static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb) 1067static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)
1131{ 1068{
1132 struct inet_timewait_sock *tw = inet_twsk(sk); 1069 struct inet_timewait_sock *tw = inet_twsk(sk);
@@ -1286,7 +1223,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1286 struct request_sock *req, 1223 struct request_sock *req,
1287 struct dst_entry *dst) 1224 struct dst_entry *dst)
1288{ 1225{
1289 struct inet6_request_sock *treq = inet6_rsk(req); 1226 struct inet6_request_sock *treq;
1290 struct ipv6_pinfo *newnp, *np = inet6_sk(sk); 1227 struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
1291 struct tcp6_sock *newtcp6sk; 1228 struct tcp6_sock *newtcp6sk;
1292 struct inet_sock *newinet; 1229 struct inet_sock *newinet;
@@ -1350,6 +1287,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1350 return newsk; 1287 return newsk;
1351 } 1288 }
1352 1289
1290 treq = inet6_rsk(req);
1353 opt = np->opt; 1291 opt = np->opt;
1354 1292
1355 if (sk_acceptq_is_full(sk)) 1293 if (sk_acceptq_is_full(sk))
@@ -1680,11 +1618,7 @@ static int tcp_v6_rcv(struct sk_buff *skb)
1680 TCP_SKB_CB(skb)->flags = ipv6_get_dsfield(ipv6_hdr(skb)); 1618 TCP_SKB_CB(skb)->flags = ipv6_get_dsfield(ipv6_hdr(skb));
1681 TCP_SKB_CB(skb)->sacked = 0; 1619 TCP_SKB_CB(skb)->sacked = 0;
1682 1620
1683 sk = __inet6_lookup(net, &tcp_hashinfo, 1621 sk = __inet6_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest);
1684 &ipv6_hdr(skb)->saddr, th->source,
1685 &ipv6_hdr(skb)->daddr, ntohs(th->dest),
1686 inet6_iif(skb));
1687
1688 if (!sk) 1622 if (!sk)
1689 goto no_tcp_socket; 1623 goto no_tcp_socket;
1690 1624