diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2015-09-22 11:02:18 +0200 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2015-09-24 17:18:41 +0200 |
commit | 646db260b843d2f758559a5483174354c304acf8 (patch) | |
tree | 73cf06896311567e8fcb75730d4461fd689a3d3f /net/sctp/protocol.c | |
parent | a645654b817feba05e5156345325d19fc85ebc9f (diff) | |
parent | 1f93e4a96c9109378204c147b3eec0d0e8100fde (diff) |
Merge tag 'v4.3-rc2' into topic/drm-misc
Backmerge Linux 4.3-rc2 because of conflicts in the dp helper code
between bugfixes and new code. Just adjacent lines really.
On top of that there's a silent conflict in the new fsl-dcu driver
merged into 4.3 and
commit 844f9111f6f54f88eb2f0fac121b82ce77193866
Author: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Date: Wed Sep 2 10:42:40 2015 +0200
drm/atomic: Make prepare_fb/cleanup_fb only take state, v3.
which Thierry Reding spotted and provided a fixup for.
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Diffstat (limited to 'net/sctp/protocol.c')
-rw-r--r-- | net/sctp/protocol.c | 48 |
1 files changed, 34 insertions, 14 deletions
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 59e80356672b..b7143337e4fa 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -487,23 +487,43 @@ static void sctp_v4_get_dst(struct sctp_transport *t, union sctp_addr *saddr, */ rcu_read_lock(); list_for_each_entry_rcu(laddr, &bp->address_list, list) { + struct net_device *odev; + if (!laddr->valid) continue; - if ((laddr->state == SCTP_ADDR_SRC) && - (AF_INET == laddr->a.sa.sa_family)) { - fl4->fl4_sport = laddr->a.v4.sin_port; - flowi4_update_output(fl4, - asoc->base.sk->sk_bound_dev_if, - RT_CONN_FLAGS(asoc->base.sk), - daddr->v4.sin_addr.s_addr, - laddr->a.v4.sin_addr.s_addr); - - rt = ip_route_output_key(sock_net(sk), fl4); - if (!IS_ERR(rt)) { - dst = &rt->dst; - goto out_unlock; - } + if (laddr->state != SCTP_ADDR_SRC || + AF_INET != laddr->a.sa.sa_family) + continue; + + fl4->fl4_sport = laddr->a.v4.sin_port; + flowi4_update_output(fl4, + asoc->base.sk->sk_bound_dev_if, + RT_CONN_FLAGS(asoc->base.sk), + daddr->v4.sin_addr.s_addr, + laddr->a.v4.sin_addr.s_addr); + + rt = ip_route_output_key(sock_net(sk), fl4); + if (IS_ERR(rt)) + continue; + + if (!dst) + dst = &rt->dst; + + /* 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) { + if (&rt->dst != dst) + dst_release(&rt->dst); + continue; } + + if (dst != &rt->dst) + dst_release(dst); + dst = &rt->dst; + break; } out_unlock: |