diff options
author | Sridhar Samudrala <sri@us.ibm.com> | 2005-06-13 18:13:05 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2005-06-13 18:13:05 -0400 |
commit | 6a6ddb2a9c11fcc3e8d7517841d28c9ea206ddef (patch) | |
tree | 9d974bc57b036ba997ba65903725e3e5b6eff5b8 /net | |
parent | cdac4e07748934e37e415437055ed591aed9eb21 (diff) |
[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>
Diffstat (limited to 'net')
-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 | } |