diff options
Diffstat (limited to 'net/ipv6/udp.c')
-rw-r--r-- | net/ipv6/udp.c | 31 |
1 files changed, 22 insertions, 9 deletions
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 69b146843a20..bf9519341fd3 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -99,7 +99,7 @@ static int udp_v6_get_port(struct sock *sk, unsigned short snum) | |||
99 | next:; | 99 | next:; |
100 | } | 100 | } |
101 | result = best; | 101 | result = best; |
102 | for(;; result += UDP_HTABLE_SIZE) { | 102 | for(i = 0; i < (1 << 16) / UDP_HTABLE_SIZE; i++, result += UDP_HTABLE_SIZE) { |
103 | if (result > sysctl_local_port_range[1]) | 103 | if (result > sysctl_local_port_range[1]) |
104 | result = sysctl_local_port_range[0] | 104 | result = sysctl_local_port_range[0] |
105 | + ((result - sysctl_local_port_range[0]) & | 105 | + ((result - sysctl_local_port_range[0]) & |
@@ -107,6 +107,8 @@ static int udp_v6_get_port(struct sock *sk, unsigned short snum) | |||
107 | if (!udp_lport_inuse(result)) | 107 | if (!udp_lport_inuse(result)) |
108 | break; | 108 | break; |
109 | } | 109 | } |
110 | if (i >= (1 << 16) / UDP_HTABLE_SIZE) | ||
111 | goto fail; | ||
110 | gotit: | 112 | gotit: |
111 | udp_port_rover = snum = result; | 113 | udp_port_rover = snum = result; |
112 | } else { | 114 | } else { |
@@ -405,9 +407,8 @@ static struct sock *udp_v6_mcast_next(struct sock *sk, | |||
405 | continue; | 407 | continue; |
406 | 408 | ||
407 | if (!ipv6_addr_any(&np->rcv_saddr)) { | 409 | if (!ipv6_addr_any(&np->rcv_saddr)) { |
408 | if (ipv6_addr_equal(&np->rcv_saddr, loc_addr)) | 410 | if (!ipv6_addr_equal(&np->rcv_saddr, loc_addr)) |
409 | return s; | 411 | continue; |
410 | continue; | ||
411 | } | 412 | } |
412 | if(!inet6_mc_check(s, loc_addr, rmt_addr)) | 413 | if(!inet6_mc_check(s, loc_addr, rmt_addr)) |
413 | continue; | 414 | continue; |
@@ -640,6 +641,7 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
640 | int tclass = -1; | 641 | int tclass = -1; |
641 | int corkreq = up->corkflag || msg->msg_flags&MSG_MORE; | 642 | int corkreq = up->corkflag || msg->msg_flags&MSG_MORE; |
642 | int err; | 643 | int err; |
644 | int connected = 0; | ||
643 | 645 | ||
644 | /* destination address check */ | 646 | /* destination address check */ |
645 | if (sin6) { | 647 | if (sin6) { |
@@ -749,6 +751,7 @@ do_udp_sendmsg: | |||
749 | fl->fl_ip_dport = inet->dport; | 751 | fl->fl_ip_dport = inet->dport; |
750 | daddr = &np->daddr; | 752 | daddr = &np->daddr; |
751 | fl->fl6_flowlabel = np->flow_label; | 753 | fl->fl6_flowlabel = np->flow_label; |
754 | connected = 1; | ||
752 | } | 755 | } |
753 | 756 | ||
754 | if (!fl->oif) | 757 | if (!fl->oif) |
@@ -771,6 +774,7 @@ do_udp_sendmsg: | |||
771 | } | 774 | } |
772 | if (!(opt->opt_nflen|opt->opt_flen)) | 775 | if (!(opt->opt_nflen|opt->opt_flen)) |
773 | opt = NULL; | 776 | opt = NULL; |
777 | connected = 0; | ||
774 | } | 778 | } |
775 | if (opt == NULL) | 779 | if (opt == NULL) |
776 | opt = np->opt; | 780 | opt = np->opt; |
@@ -788,10 +792,13 @@ do_udp_sendmsg: | |||
788 | ipv6_addr_copy(&final, &fl->fl6_dst); | 792 | ipv6_addr_copy(&final, &fl->fl6_dst); |
789 | ipv6_addr_copy(&fl->fl6_dst, rt0->addr); | 793 | ipv6_addr_copy(&fl->fl6_dst, rt0->addr); |
790 | final_p = &final; | 794 | final_p = &final; |
795 | connected = 0; | ||
791 | } | 796 | } |
792 | 797 | ||
793 | if (!fl->oif && ipv6_addr_is_multicast(&fl->fl6_dst)) | 798 | if (!fl->oif && ipv6_addr_is_multicast(&fl->fl6_dst)) { |
794 | fl->oif = np->mcast_oif; | 799 | fl->oif = np->mcast_oif; |
800 | connected = 0; | ||
801 | } | ||
795 | 802 | ||
796 | err = ip6_dst_lookup(sk, &dst, fl); | 803 | err = ip6_dst_lookup(sk, &dst, fl); |
797 | if (err) | 804 | if (err) |
@@ -847,10 +854,16 @@ do_append_data: | |||
847 | else if (!corkreq) | 854 | else if (!corkreq) |
848 | err = udp_v6_push_pending_frames(sk, up); | 855 | err = udp_v6_push_pending_frames(sk, up); |
849 | 856 | ||
850 | if (dst) | 857 | if (dst) { |
851 | ip6_dst_store(sk, dst, | 858 | if (connected) { |
852 | ipv6_addr_equal(&fl->fl6_dst, &np->daddr) ? | 859 | ip6_dst_store(sk, dst, |
853 | &np->daddr : NULL); | 860 | ipv6_addr_equal(&fl->fl6_dst, &np->daddr) ? |
861 | &np->daddr : NULL); | ||
862 | } else { | ||
863 | dst_release(dst); | ||
864 | } | ||
865 | } | ||
866 | |||
854 | if (err > 0) | 867 | if (err > 0) |
855 | err = np->recverr ? net_xmit_errno(err) : 0; | 868 | err = np->recverr ? net_xmit_errno(err) : 0; |
856 | release_sock(sk); | 869 | release_sock(sk); |