aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/tcp_ipv6.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2015-03-24 21:16:30 -0400
committerDavid S. Miller <davem@davemloft.net>2015-03-24 21:16:30 -0400
commitb1275eb32e1c543f0664ebbb9d9ec3baa9bbfcba (patch)
tree5d0b22e1e707f9ea3dcd0c3062eaaed59bc331e2 /net/ipv6/tcp_ipv6.c
parent9ead3527f5967440f2ff57fd2fa25dd0e460fc5a (diff)
parentfd3a154a00fb991872680f19021f5edbb40b4dbe (diff)
Merge branch 'listener_refactor_16'
Eric Dumazet says: ==================== tcp: listener refactor part 16 A CONFIG_PROVE_RCU=y build revealed an RCU splat I had to fix. I added const qualifiers to various md5 methods, as I expect to call them on behalf of request sock traffic even if the listener socket is not locked. This seems ok, but adding const makes the contract clearer. Note a good reduction of code size thanks to request/establish sockets convergence. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r--net/ipv6/tcp_ipv6.c50
1 files changed, 14 insertions, 36 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 4a4e6d30c448..a9568caf4675 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -486,17 +486,11 @@ static struct tcp_md5sig_key *tcp_v6_md5_do_lookup(struct sock *sk,
486} 486}
487 487
488static struct tcp_md5sig_key *tcp_v6_md5_lookup(struct sock *sk, 488static struct tcp_md5sig_key *tcp_v6_md5_lookup(struct sock *sk,
489 struct sock *addr_sk) 489 const struct sock *addr_sk)
490{ 490{
491 return tcp_v6_md5_do_lookup(sk, &addr_sk->sk_v6_daddr); 491 return tcp_v6_md5_do_lookup(sk, &addr_sk->sk_v6_daddr);
492} 492}
493 493
494static struct tcp_md5sig_key *tcp_v6_reqsk_md5_lookup(struct sock *sk,
495 struct request_sock *req)
496{
497 return tcp_v6_md5_do_lookup(sk, &inet_rsk(req)->ir_v6_rmt_addr);
498}
499
500static int tcp_v6_parse_md5_keys(struct sock *sk, char __user *optval, 494static int tcp_v6_parse_md5_keys(struct sock *sk, char __user *optval,
501 int optlen) 495 int optlen)
502{ 496{
@@ -582,9 +576,9 @@ clear_hash_noput:
582 return 1; 576 return 1;
583} 577}
584 578
585static int tcp_v6_md5_hash_skb(char *md5_hash, struct tcp_md5sig_key *key, 579static int tcp_v6_md5_hash_skb(char *md5_hash,
580 const struct tcp_md5sig_key *key,
586 const struct sock *sk, 581 const struct sock *sk,
587 const struct request_sock *req,
588 const struct sk_buff *skb) 582 const struct sk_buff *skb)
589{ 583{
590 const struct in6_addr *saddr, *daddr; 584 const struct in6_addr *saddr, *daddr;
@@ -592,12 +586,9 @@ static int tcp_v6_md5_hash_skb(char *md5_hash, struct tcp_md5sig_key *key,
592 struct hash_desc *desc; 586 struct hash_desc *desc;
593 const struct tcphdr *th = tcp_hdr(skb); 587 const struct tcphdr *th = tcp_hdr(skb);
594 588
595 if (sk) { 589 if (sk) { /* valid for establish/request sockets */
596 saddr = &inet6_sk(sk)->saddr; 590 saddr = &sk->sk_v6_rcv_saddr;
597 daddr = &sk->sk_v6_daddr; 591 daddr = &sk->sk_v6_daddr;
598 } else if (req) {
599 saddr = &inet_rsk(req)->ir_v6_loc_addr;
600 daddr = &inet_rsk(req)->ir_v6_rmt_addr;
601 } else { 592 } else {
602 const struct ipv6hdr *ip6h = ipv6_hdr(skb); 593 const struct ipv6hdr *ip6h = ipv6_hdr(skb);
603 saddr = &ip6h->saddr; 594 saddr = &ip6h->saddr;
@@ -633,8 +624,7 @@ clear_hash_noput:
633 return 1; 624 return 1;
634} 625}
635 626
636static int __tcp_v6_inbound_md5_hash(struct sock *sk, 627static bool tcp_v6_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb)
637 const struct sk_buff *skb)
638{ 628{
639 const __u8 *hash_location = NULL; 629 const __u8 *hash_location = NULL;
640 struct tcp_md5sig_key *hash_expected; 630 struct tcp_md5sig_key *hash_expected;
@@ -648,44 +638,32 @@ static int __tcp_v6_inbound_md5_hash(struct sock *sk,
648 638
649 /* We've parsed the options - do we have a hash? */ 639 /* We've parsed the options - do we have a hash? */
650 if (!hash_expected && !hash_location) 640 if (!hash_expected && !hash_location)
651 return 0; 641 return false;
652 642
653 if (hash_expected && !hash_location) { 643 if (hash_expected && !hash_location) {
654 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPMD5NOTFOUND); 644 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPMD5NOTFOUND);
655 return 1; 645 return true;
656 } 646 }
657 647
658 if (!hash_expected && hash_location) { 648 if (!hash_expected && hash_location) {
659 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPMD5UNEXPECTED); 649 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPMD5UNEXPECTED);
660 return 1; 650 return true;
661 } 651 }
662 652
663 /* check the signature */ 653 /* check the signature */
664 genhash = tcp_v6_md5_hash_skb(newhash, 654 genhash = tcp_v6_md5_hash_skb(newhash,
665 hash_expected, 655 hash_expected,
666 NULL, NULL, skb); 656 NULL, skb);
667 657
668 if (genhash || memcmp(hash_location, newhash, 16) != 0) { 658 if (genhash || memcmp(hash_location, newhash, 16) != 0) {
669 net_info_ratelimited("MD5 Hash %s for [%pI6c]:%u->[%pI6c]:%u\n", 659 net_info_ratelimited("MD5 Hash %s for [%pI6c]:%u->[%pI6c]:%u\n",
670 genhash ? "failed" : "mismatch", 660 genhash ? "failed" : "mismatch",
671 &ip6h->saddr, ntohs(th->source), 661 &ip6h->saddr, ntohs(th->source),
672 &ip6h->daddr, ntohs(th->dest)); 662 &ip6h->daddr, ntohs(th->dest));
673 return 1; 663 return true;
674 } 664 }
675 return 0; 665 return false;
676} 666}
677
678static int tcp_v6_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb)
679{
680 int ret;
681
682 rcu_read_lock();
683 ret = __tcp_v6_inbound_md5_hash(sk, skb);
684 rcu_read_unlock();
685
686 return ret;
687}
688
689#endif 667#endif
690 668
691static void tcp_v6_init_req(struct request_sock *req, struct sock *sk, 669static void tcp_v6_init_req(struct request_sock *req, struct sock *sk,
@@ -736,7 +714,7 @@ static const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = {
736 .mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - 714 .mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) -
737 sizeof(struct ipv6hdr), 715 sizeof(struct ipv6hdr),
738#ifdef CONFIG_TCP_MD5SIG 716#ifdef CONFIG_TCP_MD5SIG
739 .md5_lookup = tcp_v6_reqsk_md5_lookup, 717 .req_md5_lookup = tcp_v6_md5_lookup,
740 .calc_md5_hash = tcp_v6_md5_hash_skb, 718 .calc_md5_hash = tcp_v6_md5_hash_skb,
741#endif 719#endif
742 .init_req = tcp_v6_init_req, 720 .init_req = tcp_v6_init_req,
@@ -893,7 +871,7 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb)
893 if (!key) 871 if (!key)
894 goto release_sk1; 872 goto release_sk1;
895 873
896 genhash = tcp_v6_md5_hash_skb(newhash, key, NULL, NULL, skb); 874 genhash = tcp_v6_md5_hash_skb(newhash, key, NULL, skb);
897 if (genhash || memcmp(hash_location, newhash, 16) != 0) 875 if (genhash || memcmp(hash_location, newhash, 16) != 0)
898 goto release_sk1; 876 goto release_sk1;
899 } else { 877 } else {