aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/ipv6.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp/ipv6.c')
-rw-r--r--net/sctp/ipv6.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 51c048d256f5..593c80162913 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -262,22 +262,27 @@ static struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc,
262 __u8 matchlen = 0; 262 __u8 matchlen = 0;
263 __u8 bmatchlen; 263 __u8 bmatchlen;
264 sctp_scope_t scope; 264 sctp_scope_t scope;
265 int err = 0;
266 265
267 memset(fl6, 0, sizeof(struct flowi6)); 266 memset(fl6, 0, sizeof(struct flowi6));
268 ipv6_addr_copy(&fl6->daddr, &daddr->v6.sin6_addr); 267 ipv6_addr_copy(&fl6->daddr, &daddr->v6.sin6_addr);
268 fl6->fl6_dport = daddr->v6.sin6_port;
269 fl6->flowi6_proto = IPPROTO_SCTP;
269 if (ipv6_addr_type(&daddr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) 270 if (ipv6_addr_type(&daddr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL)
270 fl6->flowi6_oif = daddr->v6.sin6_scope_id; 271 fl6->flowi6_oif = daddr->v6.sin6_scope_id;
271 272
272 273
273 SCTP_DEBUG_PRINTK("%s: DST=%pI6 ", __func__, &fl6->daddr); 274 SCTP_DEBUG_PRINTK("%s: DST=%pI6 ", __func__, &fl6->daddr);
274 275
276 if (asoc)
277 fl6->fl6_sport = htons(asoc->base.bind_addr.port);
278
275 if (saddr) { 279 if (saddr) {
276 ipv6_addr_copy(&fl6->saddr, &saddr->v6.sin6_addr); 280 ipv6_addr_copy(&fl6->saddr, &saddr->v6.sin6_addr);
281 fl6->fl6_sport = saddr->v6.sin6_port;
277 SCTP_DEBUG_PRINTK("SRC=%pI6 - ", &fl6->saddr); 282 SCTP_DEBUG_PRINTK("SRC=%pI6 - ", &fl6->saddr);
278 } 283 }
279 284
280 err = ip6_dst_lookup(sk, &dst, fl6); 285 dst = ip6_dst_lookup_flow(sk, fl6, NULL, false);
281 if (!asoc || saddr) 286 if (!asoc || saddr)
282 goto out; 287 goto out;
283 288
@@ -286,7 +291,7 @@ static struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc,
286 /* ip6_dst_lookup has filled in the fl6->saddr for us. Check 291 /* ip6_dst_lookup has filled in the fl6->saddr for us. Check
287 * to see if we can use it. 292 * to see if we can use it.
288 */ 293 */
289 if (!err) { 294 if (!IS_ERR(dst)) {
290 /* Walk through the bind address list and look for a bind 295 /* Walk through the bind address list and look for a bind
291 * address that matches the source address of the returned dst. 296 * address that matches the source address of the returned dst.
292 */ 297 */
@@ -330,11 +335,12 @@ static struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc,
330 rcu_read_unlock(); 335 rcu_read_unlock();
331 if (baddr) { 336 if (baddr) {
332 ipv6_addr_copy(&fl6->saddr, &baddr->v6.sin6_addr); 337 ipv6_addr_copy(&fl6->saddr, &baddr->v6.sin6_addr);
333 err = ip6_dst_lookup(sk, &dst, fl6); 338 fl6->fl6_sport = baddr->v6.sin6_port;
339 dst = ip6_dst_lookup_flow(sk, fl6, NULL, false);
334 } 340 }
335 341
336out: 342out:
337 if (!err) { 343 if (!IS_ERR(dst)) {
338 struct rt6_info *rt; 344 struct rt6_info *rt;
339 rt = (struct rt6_info *)dst; 345 rt = (struct rt6_info *)dst;
340 SCTP_DEBUG_PRINTK("rt6_dst:%pI6 rt6_src:%pI6\n", 346 SCTP_DEBUG_PRINTK("rt6_dst:%pI6 rt6_src:%pI6\n",