mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-27 06:04:23 +08:00
sctp: check ipv6 addr with sk_bound_dev if set
When binding to an ipv6 address, it calls ipv6_chk_addr() to check if this address is on any dev. If a socket binds to a l3mdev but no dev is passed to do this check, all l3mdev and slaves will be skipped and the check will fail. This patch is to pass the bound_dev to make sure the devices under the same l3mdev can be returned in ipv6_chk_addr(). When the bound_dev is not a l3mdev or l3slave, l3mdev_master_dev_rcu() will return NULL in __ipv6_chk_addr_and_flags(), it will keep compitable with before when NULL dev was passed. Signed-off-by: Xin Long <lucien.xin@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
26943aefa8
commit
6fe1e52490
@ -680,9 +680,11 @@ static int sctp_v6_is_any(const union sctp_addr *addr)
|
||||
/* Should this be available for binding? */
|
||||
static int sctp_v6_available(union sctp_addr *addr, struct sctp_sock *sp)
|
||||
{
|
||||
int type;
|
||||
struct net *net = sock_net(&sp->inet.sk);
|
||||
const struct in6_addr *in6 = (const struct in6_addr *)&addr->v6.sin6_addr;
|
||||
struct sock *sk = &sp->inet.sk;
|
||||
struct net *net = sock_net(sk);
|
||||
struct net_device *dev = NULL;
|
||||
int type;
|
||||
|
||||
type = ipv6_addr_type(in6);
|
||||
if (IPV6_ADDR_ANY == type)
|
||||
@ -696,8 +698,14 @@ static int sctp_v6_available(union sctp_addr *addr, struct sctp_sock *sp)
|
||||
if (!(type & IPV6_ADDR_UNICAST))
|
||||
return 0;
|
||||
|
||||
if (sk->sk_bound_dev_if) {
|
||||
dev = dev_get_by_index_rcu(net, sk->sk_bound_dev_if);
|
||||
if (!dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ipv6_can_nonlocal_bind(net, &sp->inet) ||
|
||||
ipv6_chk_addr(net, in6, NULL, 0);
|
||||
ipv6_chk_addr(net, in6, dev, 0);
|
||||
}
|
||||
|
||||
/* This function checks if the address is a valid address to be used for
|
||||
|
Loading…
Reference in New Issue
Block a user