Commit 57816cbc authored by David S. Miller's avatar David S. Miller

Merge branch 'sctp-src-addr'

Marcelo Ricardo Leitner says:

====================
sctp: fix src address selection if using secondary address

This series improves the way SCTP chooses its src address so that the
choosen one will always belong to the interface being used for output.

v1->v2:
 - split out the refactoring from the fix itself
 - Doing a full reverse routing as in v1 is not necessary. Only looking
   for the interface that has the address and comparing its number is
   enough.
====================
Acked-by: default avatarVlad Yasevich <vyasevich@gmail.com>
Acked-by: default avatarNeil Horman <nhorman@tuxdriver.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 7177a3b0 0ca50d12
...@@ -487,23 +487,35 @@ static void sctp_v4_get_dst(struct sctp_transport *t, union sctp_addr *saddr, ...@@ -487,23 +487,35 @@ static void sctp_v4_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
*/ */
rcu_read_lock(); rcu_read_lock();
list_for_each_entry_rcu(laddr, &bp->address_list, list) { list_for_each_entry_rcu(laddr, &bp->address_list, list) {
struct net_device *odev;
if (!laddr->valid) if (!laddr->valid)
continue; continue;
if ((laddr->state == SCTP_ADDR_SRC) && if (laddr->state != SCTP_ADDR_SRC ||
(AF_INET == laddr->a.sa.sa_family)) { AF_INET != laddr->a.sa.sa_family)
fl4->fl4_sport = laddr->a.v4.sin_port; continue;
flowi4_update_output(fl4,
asoc->base.sk->sk_bound_dev_if, fl4->fl4_sport = laddr->a.v4.sin_port;
RT_CONN_FLAGS(asoc->base.sk), flowi4_update_output(fl4,
daddr->v4.sin_addr.s_addr, asoc->base.sk->sk_bound_dev_if,
laddr->a.v4.sin_addr.s_addr); RT_CONN_FLAGS(asoc->base.sk),
daddr->v4.sin_addr.s_addr,
rt = ip_route_output_key(sock_net(sk), fl4); laddr->a.v4.sin_addr.s_addr);
if (!IS_ERR(rt)) {
dst = &rt->dst; rt = ip_route_output_key(sock_net(sk), fl4);
goto out_unlock; if (IS_ERR(rt))
} continue;
}
/* Ensure the src address belongs to the output
* interface.
*/
odev = __ip_dev_find(sock_net(sk), laddr->a.v4.sin_addr.s_addr,
false);
if (!odev || odev->ifindex != fl4->flowi4_oif)
continue;
dst = &rt->dst;
break;
} }
out_unlock: out_unlock:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment