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.c44
1 files changed, 18 insertions, 26 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index cff778b23a7f..10e22fd48222 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -69,7 +69,8 @@
69#include <linux/scatterlist.h> 69#include <linux/scatterlist.h>
70 70
71static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb); 71static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb);
72static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req); 72static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
73 struct request_sock *req);
73 74
74static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); 75static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb);
75 76
@@ -748,7 +749,7 @@ static int tcp_v6_md5_hash_pseudoheader(struct tcp_md5sig_pool *hp,
748 ipv6_addr_copy(&bp->saddr, saddr); 749 ipv6_addr_copy(&bp->saddr, saddr);
749 ipv6_addr_copy(&bp->daddr, daddr); 750 ipv6_addr_copy(&bp->daddr, daddr);
750 bp->protocol = cpu_to_be32(IPPROTO_TCP); 751 bp->protocol = cpu_to_be32(IPPROTO_TCP);
751 bp->len = cpu_to_be16(nbytes); 752 bp->len = cpu_to_be32(nbytes);
752 753
753 sg_init_one(&sg, bp, sizeof(*bp)); 754 sg_init_one(&sg, bp, sizeof(*bp));
754 return crypto_hash_update(&hp->md5_desc, &sg, sizeof(*bp)); 755 return crypto_hash_update(&hp->md5_desc, &sg, sizeof(*bp));
@@ -849,28 +850,17 @@ static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb)
849 hash_expected = tcp_v6_md5_do_lookup(sk, &ip6h->saddr); 850 hash_expected = tcp_v6_md5_do_lookup(sk, &ip6h->saddr);
850 hash_location = tcp_parse_md5sig_option(th); 851 hash_location = tcp_parse_md5sig_option(th);
851 852
852 /* do we have a hash as expected? */ 853 /* We've parsed the options - do we have a hash? */
853 if (!hash_expected) { 854 if (!hash_expected && !hash_location)
854 if (!hash_location) 855 return 0;
855 return 0; 856
856 if (net_ratelimit()) { 857 if (hash_expected && !hash_location) {
857 printk(KERN_INFO "MD5 Hash NOT expected but found " 858 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPMD5NOTFOUND);
858 "(" NIP6_FMT ", %u)->"
859 "(" NIP6_FMT ", %u)\n",
860 NIP6(ip6h->saddr), ntohs(th->source),
861 NIP6(ip6h->daddr), ntohs(th->dest));
862 }
863 return 1; 859 return 1;
864 } 860 }
865 861
866 if (!hash_location) { 862 if (!hash_expected && hash_location) {
867 if (net_ratelimit()) { 863 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPMD5UNEXPECTED);
868 printk(KERN_INFO "MD5 Hash expected but NOT found "
869 "(" NIP6_FMT ", %u)->"
870 "(" NIP6_FMT ", %u)\n",
871 NIP6(ip6h->saddr), ntohs(th->source),
872 NIP6(ip6h->daddr), ntohs(th->dest));
873 }
874 return 1; 864 return 1;
875 } 865 }
876 866
@@ -1060,7 +1050,7 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
1060 struct tcphdr *th = tcp_hdr(skb), *t1; 1050 struct tcphdr *th = tcp_hdr(skb), *t1;
1061 struct sk_buff *buff; 1051 struct sk_buff *buff;
1062 struct flowi fl; 1052 struct flowi fl;
1063 struct net *net = dev_net(skb->dev); 1053 struct net *net = dev_net(skb->dst->dev);
1064 struct sock *ctl_sk = net->ipv6.tcp_sk; 1054 struct sock *ctl_sk = net->ipv6.tcp_sk;
1065 unsigned int tot_len = sizeof(struct tcphdr); 1055 unsigned int tot_len = sizeof(struct tcphdr);
1066 __be32 *topt; 1056 __be32 *topt;
@@ -1105,8 +1095,8 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
1105 *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | 1095 *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
1106 (TCPOPT_MD5SIG << 8) | TCPOLEN_MD5SIG); 1096 (TCPOPT_MD5SIG << 8) | TCPOLEN_MD5SIG);
1107 tcp_v6_md5_hash_hdr((__u8 *)topt, key, 1097 tcp_v6_md5_hash_hdr((__u8 *)topt, key,
1108 &ipv6_hdr(skb)->daddr, 1098 &ipv6_hdr(skb)->saddr,
1109 &ipv6_hdr(skb)->saddr, t1); 1099 &ipv6_hdr(skb)->daddr, t1);
1110 } 1100 }
1111#endif 1101#endif
1112 1102
@@ -1149,10 +1139,11 @@ static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)
1149 inet_twsk_put(tw); 1139 inet_twsk_put(tw);
1150} 1140}
1151 1141
1152static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req) 1142static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
1143 struct request_sock *req)
1153{ 1144{
1154 tcp_v6_send_ack(skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent, 1145 tcp_v6_send_ack(skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent,
1155 tcp_v6_md5_do_lookup(skb->sk, &ipv6_hdr(skb)->daddr)); 1146 tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr));
1156} 1147}
1157 1148
1158 1149
@@ -2157,6 +2148,7 @@ static int tcpv6_net_init(struct net *net)
2157static void tcpv6_net_exit(struct net *net) 2148static void tcpv6_net_exit(struct net *net)
2158{ 2149{
2159 inet_ctl_sock_destroy(net->ipv6.tcp_sk); 2150 inet_ctl_sock_destroy(net->ipv6.tcp_sk);
2151 inet_twsk_purge(net, &tcp_hashinfo, &tcp_death_row, AF_INET6);
2160} 2152}
2161 2153
2162static struct pernet_operations tcpv6_net_ops = { 2154static struct pernet_operations tcpv6_net_ops = {