diff options
Diffstat (limited to 'net/sctp/protocol.c')
-rw-r--r-- | net/sctp/protocol.c | 40 |
1 files changed, 22 insertions, 18 deletions
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 7b523e3f551f..616a9428e0c4 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -205,26 +205,30 @@ int sctp_copy_local_addr_list(struct net *net, struct sctp_bind_addr *bp, list_for_each_entry_rcu(addr, &net->sctp.local_addr_list, list) { if (!addr->valid) continue; - if (sctp_in_scope(net, &addr->a, scope)) { - /* Now that the address is in scope, check to see if - * the address type is really supported by the local - * sock as well as the remote peer. - */ - if ((((AF_INET == addr->a.sa.sa_family) && - (copy_flags & SCTP_ADDR4_PEERSUPP))) || - (((AF_INET6 == addr->a.sa.sa_family) && - (copy_flags & SCTP_ADDR6_ALLOWED) && - (copy_flags & SCTP_ADDR6_PEERSUPP)))) { - error = sctp_add_bind_addr(bp, &addr->a, - sizeof(addr->a), - SCTP_ADDR_SRC, GFP_ATOMIC); - if (error) - goto end_copy; - } - } + if (!sctp_in_scope(net, &addr->a, scope)) + continue; + + /* Now that the address is in scope, check to see if + * the address type is really supported by the local + * sock as well as the remote peer. + */ + if (addr->a.sa.sa_family == AF_INET && + !(copy_flags & SCTP_ADDR4_PEERSUPP)) + continue; + if (addr->a.sa.sa_family == AF_INET6 && + (!(copy_flags & SCTP_ADDR6_ALLOWED) || + !(copy_flags & SCTP_ADDR6_PEERSUPP))) + continue; + + if (sctp_bind_addr_state(bp, &addr->a) != -1) + continue; + + error = sctp_add_bind_addr(bp, &addr->a, sizeof(addr->a), + SCTP_ADDR_SRC, GFP_ATOMIC); + if (error) + break; } -end_copy: rcu_read_unlock(); return error; } |