[SCTP] Fix incorrect setting of sk_bound_dev_if when binding/sending to a ipv6 link local address.

Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by Sridhar Samudrala and committed by David S. Miller 6a6ddb2a cdac4e07

Changed files
+15 -21
net
sctp
+15 -21
net/sctp/ipv6.c
··· 812 812 if (addr->sa.sa_family != AF_INET6) 813 813 af = sctp_get_af_specific(addr->sa.sa_family); 814 814 else { 815 - struct sock *sk; 816 815 int type = ipv6_addr_type(&addr->v6.sin6_addr); 817 - sk = sctp_opt2sk(opt); 818 - if (type & IPV6_ADDR_LINKLOCAL) { 819 - /* Note: Behavior similar to af_inet6.c: 820 - * 1) Overrides previous bound_dev_if 821 - * 2) Destructive even if bind isn't successful. 822 - */ 816 + struct net_device *dev; 823 817 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) 818 + if (type & IPV6_ADDR_LINKLOCAL) { 819 + if (!addr->v6.sin6_scope_id) 827 820 return 0; 821 + dev = dev_get_by_index(addr->v6.sin6_scope_id); 822 + if (!dev) 823 + return 0; 824 + dev_put(dev); 828 825 } 829 826 af = opt->pf->af; 830 827 } 831 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 832 * has already been taken care of. 836 833 */ 837 834 static int sctp_inet6_send_verify(struct sctp_sock *opt, union sctp_addr *addr) ··· 839 842 if (addr->sa.sa_family != AF_INET6) 840 843 af = sctp_get_af_specific(addr->sa.sa_family); 841 844 else { 842 - struct sock *sk; 843 845 int type = ipv6_addr_type(&addr->v6.sin6_addr); 844 - sk = sctp_opt2sk(opt); 845 - if (type & IPV6_ADDR_LINKLOCAL) { 846 - /* Note: Behavior similar to af_inet6.c: 847 - * 1) Overrides previous bound_dev_if 848 - * 2) Destructive even if bind isn't successful. 849 - */ 846 + struct net_device *dev; 850 847 851 - if (addr->v6.sin6_scope_id) 852 - sk->sk_bound_dev_if = addr->v6.sin6_scope_id; 853 - if (!sk->sk_bound_dev_if) 848 + if (type & IPV6_ADDR_LINKLOCAL) { 849 + if (!addr->v6.sin6_scope_id) 854 850 return 0; 851 + dev = dev_get_by_index(addr->v6.sin6_scope_id); 852 + if (!dev) 853 + return 0; 854 + dev_put(dev); 855 855 } 856 856 af = opt->pf->af; 857 857 }