diff options
Diffstat (limited to 'net/sctp/ipv6.c')
| -rw-r--r-- | net/sctp/ipv6.c | 36 |
1 files changed, 15 insertions, 21 deletions
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index c9d9ea064734..c7e42d125b9c 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c | |||
| @@ -812,26 +812,23 @@ static int sctp_inet6_bind_verify(struct sctp_sock *opt, union sctp_addr *addr) | |||
| 812 | if (addr->sa.sa_family != AF_INET6) | 812 | if (addr->sa.sa_family != AF_INET6) |
| 813 | af = sctp_get_af_specific(addr->sa.sa_family); | 813 | af = sctp_get_af_specific(addr->sa.sa_family); |
| 814 | else { | 814 | else { |
| 815 | struct sock *sk; | ||
| 816 | int type = ipv6_addr_type(&addr->v6.sin6_addr); | 815 | int type = ipv6_addr_type(&addr->v6.sin6_addr); |
| 817 | sk = sctp_opt2sk(opt); | 816 | struct net_device *dev; |
| 817 | |||
| 818 | if (type & IPV6_ADDR_LINKLOCAL) { | 818 | if (type & IPV6_ADDR_LINKLOCAL) { |
| 819 | /* Note: Behavior similar to af_inet6.c: | 819 | if (!addr->v6.sin6_scope_id) |
| 820 | * 1) Overrides previous bound_dev_if | 820 | return 0; |
| 821 | * 2) Destructive even if bind isn't successful. | 821 | dev = dev_get_by_index(addr->v6.sin6_scope_id); |
| 822 | */ | 822 | if (!dev) |
| 823 | |||
| 824 | if (addr->v6.sin6_scope_id) | ||
| 825 | sk->sk_bound_dev_if = addr->v6.sin6_scope_id; | ||
| 826 | if (!sk->sk_bound_dev_if) | ||
| 827 | return 0; | 823 | return 0; |
| 824 | dev_put(dev); | ||
| 828 | } | 825 | } |
| 829 | af = opt->pf->af; | 826 | af = opt->pf->af; |
| 830 | } | 827 | } |
| 831 | return af->available(addr, opt); | 828 | return af->available(addr, opt); |
| 832 | } | 829 | } |
| 833 | 830 | ||
| 834 | /* Verify that the provided sockaddr looks bindable. Common verification, | 831 | /* Verify that the provided sockaddr looks sendable. Common verification, |
| 835 | * has already been taken care of. | 832 | * has already been taken care of. |
| 836 | */ | 833 | */ |
| 837 | static int sctp_inet6_send_verify(struct sctp_sock *opt, union sctp_addr *addr) | 834 | static int sctp_inet6_send_verify(struct sctp_sock *opt, union sctp_addr *addr) |
| @@ -842,19 +839,16 @@ static int sctp_inet6_send_verify(struct sctp_sock *opt, union sctp_addr *addr) | |||
| 842 | if (addr->sa.sa_family != AF_INET6) | 839 | if (addr->sa.sa_family != AF_INET6) |
| 843 | af = sctp_get_af_specific(addr->sa.sa_family); | 840 | af = sctp_get_af_specific(addr->sa.sa_family); |
| 844 | else { | 841 | else { |
| 845 | struct sock *sk; | ||
| 846 | int type = ipv6_addr_type(&addr->v6.sin6_addr); | 842 | int type = ipv6_addr_type(&addr->v6.sin6_addr); |
| 847 | sk = sctp_opt2sk(opt); | 843 | struct net_device *dev; |
| 844 | |||
| 848 | if (type & IPV6_ADDR_LINKLOCAL) { | 845 | if (type & IPV6_ADDR_LINKLOCAL) { |
| 849 | /* Note: Behavior similar to af_inet6.c: | 846 | if (!addr->v6.sin6_scope_id) |
| 850 | * 1) Overrides previous bound_dev_if | 847 | return 0; |
| 851 | * 2) Destructive even if bind isn't successful. | 848 | dev = dev_get_by_index(addr->v6.sin6_scope_id); |
| 852 | */ | 849 | if (!dev) |
| 853 | |||
| 854 | if (addr->v6.sin6_scope_id) | ||
| 855 | sk->sk_bound_dev_if = addr->v6.sin6_scope_id; | ||
| 856 | if (!sk->sk_bound_dev_if) | ||
| 857 | return 0; | 850 | return 0; |
| 851 | dev_put(dev); | ||
| 858 | } | 852 | } |
| 859 | af = opt->pf->af; | 853 | af = opt->pf->af; |
| 860 | } | 854 | } |
