diff options
Diffstat (limited to 'net/sctp/ipv6.c')
-rw-r--r-- | net/sctp/ipv6.c | 16 |
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 | ||
336 | out: | 342 | out: |
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", |