diff options
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 44 |
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 | ||
71 | static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb); | 71 | static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb); |
72 | static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req); | 72 | static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb, |
73 | struct request_sock *req); | ||
73 | 74 | ||
74 | static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); | 75 | static 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 | ||
1152 | static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req) | 1142 | static 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) | |||
2157 | static void tcpv6_net_exit(struct net *net) | 2148 | static 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 | ||
2162 | static struct pernet_operations tcpv6_net_ops = { | 2154 | static struct pernet_operations tcpv6_net_ops = { |