aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/sctp/structs.h14
-rw-r--r--net/sctp/ipv6.c161
-rw-r--r--net/sctp/protocol.c47
-rw-r--r--net/sctp/socket.c2
-rw-r--r--net/sctp/transport.c15
5 files changed, 112 insertions, 127 deletions
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 5c9bada51d2d..1d465d62f34f 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -566,17 +566,15 @@ struct sctp_af {
566 int __user *optlen); 566 int __user *optlen);
567 struct dst_entry *(*get_dst) (struct sctp_association *asoc, 567 struct dst_entry *(*get_dst) (struct sctp_association *asoc,
568 union sctp_addr *daddr, 568 union sctp_addr *daddr,
569 union sctp_addr *saddr); 569 union sctp_addr *saddr,
570 struct flowi *fl,
571 struct sock *sk);
570 void (*get_saddr) (struct sctp_sock *sk, 572 void (*get_saddr) (struct sctp_sock *sk,
571 struct sctp_association *asoc, 573 struct sctp_transport *t,
572 struct dst_entry *dst,
573 union sctp_addr *daddr, 574 union sctp_addr *daddr,
574 union sctp_addr *saddr); 575 struct flowi *fl);
575 void (*copy_addrlist) (struct list_head *, 576 void (*copy_addrlist) (struct list_head *,
576 struct net_device *); 577 struct net_device *);
577 void (*dst_saddr) (union sctp_addr *saddr,
578 struct dst_entry *dst,
579 __be16 port);
580 int (*cmp_addr) (const union sctp_addr *addr1, 578 int (*cmp_addr) (const union sctp_addr *addr1,
581 const union sctp_addr *addr2); 579 const union sctp_addr *addr2);
582 void (*addr_copy) (union sctp_addr *dst, 580 void (*addr_copy) (union sctp_addr *dst,
@@ -1061,7 +1059,7 @@ void sctp_transport_set_owner(struct sctp_transport *,
1061 struct sctp_association *); 1059 struct sctp_association *);
1062void sctp_transport_route(struct sctp_transport *, union sctp_addr *, 1060void sctp_transport_route(struct sctp_transport *, union sctp_addr *,
1063 struct sctp_sock *); 1061 struct sctp_sock *);
1064void sctp_transport_pmtu(struct sctp_transport *); 1062void sctp_transport_pmtu(struct sctp_transport *, struct sock *sk);
1065void sctp_transport_free(struct sctp_transport *); 1063void sctp_transport_free(struct sctp_transport *);
1066void sctp_transport_reset_timers(struct sctp_transport *); 1064void sctp_transport_reset_timers(struct sctp_transport *);
1067void sctp_transport_hold(struct sctp_transport *); 1065void sctp_transport_hold(struct sctp_transport *);
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 3a571d6614f9..51c048d256f5 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -82,6 +82,10 @@
82 82
83static inline int sctp_v6_addr_match_len(union sctp_addr *s1, 83static inline int sctp_v6_addr_match_len(union sctp_addr *s1,
84 union sctp_addr *s2); 84 union sctp_addr *s2);
85static void sctp_v6_to_addr(union sctp_addr *addr, struct in6_addr *saddr,
86 __be16 port);
87static int sctp_v6_cmp_addr(const union sctp_addr *addr1,
88 const union sctp_addr *addr2);
85 89
86/* Event handler for inet6 address addition/deletion events. 90/* Event handler for inet6 address addition/deletion events.
87 * The sctp_local_addr_list needs to be protocted by a spin lock since 91 * The sctp_local_addr_list needs to be protocted by a spin lock since
@@ -245,73 +249,99 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport)
245 */ 249 */
246static struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc, 250static struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc,
247 union sctp_addr *daddr, 251 union sctp_addr *daddr,
248 union sctp_addr *saddr) 252 union sctp_addr *saddr,
253 struct flowi *fl,
254 struct sock *sk)
249{ 255{
250 struct dst_entry *dst = NULL; 256 struct dst_entry *dst = NULL;
251 struct flowi6 fl6; 257 struct flowi6 *fl6 = &fl->u.ip6;
252 struct sctp_bind_addr *bp; 258 struct sctp_bind_addr *bp;
253 struct sctp_sockaddr_entry *laddr; 259 struct sctp_sockaddr_entry *laddr;
254 union sctp_addr *baddr = NULL; 260 union sctp_addr *baddr = NULL;
261 union sctp_addr dst_saddr;
255 __u8 matchlen = 0; 262 __u8 matchlen = 0;
256 __u8 bmatchlen; 263 __u8 bmatchlen;
257 sctp_scope_t scope; 264 sctp_scope_t scope;
265 int err = 0;
258 266
259 memset(&fl6, 0, sizeof(fl6)); 267 memset(fl6, 0, sizeof(struct flowi6));
260 ipv6_addr_copy(&fl6.daddr, &daddr->v6.sin6_addr); 268 ipv6_addr_copy(&fl6->daddr, &daddr->v6.sin6_addr);
261 if (ipv6_addr_type(&daddr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) 269 if (ipv6_addr_type(&daddr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL)
262 fl6.flowi6_oif = daddr->v6.sin6_scope_id; 270 fl6->flowi6_oif = daddr->v6.sin6_scope_id;
263 271
264 272
265 SCTP_DEBUG_PRINTK("%s: DST=%pI6 ", __func__, &fl6.daddr); 273 SCTP_DEBUG_PRINTK("%s: DST=%pI6 ", __func__, &fl6->daddr);
266 274
267 if (saddr) { 275 if (saddr) {
268 ipv6_addr_copy(&fl6.saddr, &saddr->v6.sin6_addr); 276 ipv6_addr_copy(&fl6->saddr, &saddr->v6.sin6_addr);
269 SCTP_DEBUG_PRINTK("SRC=%pI6 - ", &fl6.saddr); 277 SCTP_DEBUG_PRINTK("SRC=%pI6 - ", &fl6->saddr);
270 } 278 }
271 279
272 dst = ip6_route_output(&init_net, NULL, &fl6); 280 err = ip6_dst_lookup(sk, &dst, fl6);
273 if (!asoc || saddr) 281 if (!asoc || saddr)
274 goto out; 282 goto out;
275 283
276 if (dst->error) { 284 bp = &asoc->base.bind_addr;
277 dst_release(dst); 285 scope = sctp_scope(daddr);
278 dst = NULL; 286 /* ip6_dst_lookup has filled in the fl6->saddr for us. Check
279 bp = &asoc->base.bind_addr; 287 * to see if we can use it.
280 scope = sctp_scope(daddr); 288 */
281 /* Walk through the bind address list and try to get a dst that 289 if (!err) {
282 * matches a bind address as the source address. 290 /* Walk through the bind address list and look for a bind
291 * address that matches the source address of the returned dst.
283 */ 292 */
293 sctp_v6_to_addr(&dst_saddr, &fl6->saddr, htons(bp->port));
284 rcu_read_lock(); 294 rcu_read_lock();
285 list_for_each_entry_rcu(laddr, &bp->address_list, list) { 295 list_for_each_entry_rcu(laddr, &bp->address_list, list) {
286 if (!laddr->valid) 296 if (!laddr->valid || (laddr->state != SCTP_ADDR_SRC))
287 continue; 297 continue;
288 if ((laddr->state == SCTP_ADDR_SRC) && 298
289 (laddr->a.sa.sa_family == AF_INET6) && 299 /* Do not compare against v4 addrs */
290 (scope <= sctp_scope(&laddr->a))) { 300 if ((laddr->a.sa.sa_family == AF_INET6) &&
291 bmatchlen = sctp_v6_addr_match_len(daddr, 301 (sctp_v6_cmp_addr(&dst_saddr, &laddr->a))) {
292 &laddr->a); 302 rcu_read_unlock();
293 if (!baddr || (matchlen < bmatchlen)) { 303 goto out;
294 baddr = &laddr->a;
295 matchlen = bmatchlen;
296 }
297 } 304 }
298 } 305 }
299 rcu_read_unlock(); 306 rcu_read_unlock();
300 if (baddr) { 307 /* None of the bound addresses match the source address of the
301 ipv6_addr_copy(&fl6.saddr, &baddr->v6.sin6_addr); 308 * dst. So release it.
302 dst = ip6_route_output(&init_net, NULL, &fl6); 309 */
310 dst_release(dst);
311 dst = NULL;
312 }
313
314 /* Walk through the bind address list and try to get the
315 * best source address for a given destination.
316 */
317 rcu_read_lock();
318 list_for_each_entry_rcu(laddr, &bp->address_list, list) {
319 if (!laddr->valid && laddr->state != SCTP_ADDR_SRC)
320 continue;
321 if ((laddr->a.sa.sa_family == AF_INET6) &&
322 (scope <= sctp_scope(&laddr->a))) {
323 bmatchlen = sctp_v6_addr_match_len(daddr, &laddr->a);
324 if (!baddr || (matchlen < bmatchlen)) {
325 baddr = &laddr->a;
326 matchlen = bmatchlen;
327 }
303 } 328 }
304 } 329 }
330 rcu_read_unlock();
331 if (baddr) {
332 ipv6_addr_copy(&fl6->saddr, &baddr->v6.sin6_addr);
333 err = ip6_dst_lookup(sk, &dst, fl6);
334 }
335
305out: 336out:
306 if (!dst->error) { 337 if (!err) {
307 struct rt6_info *rt; 338 struct rt6_info *rt;
308 rt = (struct rt6_info *)dst; 339 rt = (struct rt6_info *)dst;
309 SCTP_DEBUG_PRINTK("rt6_dst:%pI6 rt6_src:%pI6\n", 340 SCTP_DEBUG_PRINTK("rt6_dst:%pI6 rt6_src:%pI6\n",
310 &rt->rt6i_dst.addr, &rt->rt6i_src.addr); 341 &rt->rt6i_dst.addr, &fl6->saddr);
311 return dst; 342 return dst;
312 } 343 }
313 SCTP_DEBUG_PRINTK("NO ROUTE\n"); 344 SCTP_DEBUG_PRINTK("NO ROUTE\n");
314 dst_release(dst);
315 return NULL; 345 return NULL;
316} 346}
317 347
@@ -328,64 +358,21 @@ static inline int sctp_v6_addr_match_len(union sctp_addr *s1,
328 * and asoc's bind address list. 358 * and asoc's bind address list.
329 */ 359 */
330static void sctp_v6_get_saddr(struct sctp_sock *sk, 360static void sctp_v6_get_saddr(struct sctp_sock *sk,
331 struct sctp_association *asoc, 361 struct sctp_transport *t,
332 struct dst_entry *dst,
333 union sctp_addr *daddr, 362 union sctp_addr *daddr,
334 union sctp_addr *saddr) 363 struct flowi *fl)
335{ 364{
336 struct sctp_bind_addr *bp; 365 struct flowi6 *fl6 = &fl->u.ip6;
337 struct sctp_sockaddr_entry *laddr; 366 union sctp_addr *saddr = &t->saddr;
338 sctp_scope_t scope;
339 union sctp_addr *baddr = NULL;
340 __u8 matchlen = 0;
341 __u8 bmatchlen;
342 367
343 SCTP_DEBUG_PRINTK("%s: asoc:%p dst:%p daddr:%pI6 ", 368 SCTP_DEBUG_PRINTK("%s: asoc:%p dst:%p daddr:%pI6 ",
344 __func__, asoc, dst, &daddr->v6.sin6_addr); 369 __func__, t->asoc, t->dst, &daddr->v6.sin6_addr);
345
346 if (!asoc) {
347 ipv6_dev_get_saddr(sock_net(sctp_opt2sk(sk)),
348 dst ? ip6_dst_idev(dst)->dev : NULL,
349 &daddr->v6.sin6_addr,
350 inet6_sk(&sk->inet.sk)->srcprefs,
351 &saddr->v6.sin6_addr);
352 SCTP_DEBUG_PRINTK("saddr from ipv6_get_saddr: %pI6\n",
353 &saddr->v6.sin6_addr);
354 return;
355 }
356
357 scope = sctp_scope(daddr);
358 370
359 bp = &asoc->base.bind_addr;
360
361 /* Go through the bind address list and find the best source address
362 * that matches the scope of the destination address.
363 */
364 rcu_read_lock();
365 list_for_each_entry_rcu(laddr, &bp->address_list, list) {
366 if (!laddr->valid)
367 continue;
368 if ((laddr->state == SCTP_ADDR_SRC) &&
369 (laddr->a.sa.sa_family == AF_INET6) &&
370 (scope <= sctp_scope(&laddr->a))) {
371 bmatchlen = sctp_v6_addr_match_len(daddr, &laddr->a);
372 if (!baddr || (matchlen < bmatchlen)) {
373 baddr = &laddr->a;
374 matchlen = bmatchlen;
375 }
376 }
377 }
378 371
379 if (baddr) { 372 if (t->dst) {
380 memcpy(saddr, baddr, sizeof(union sctp_addr)); 373 saddr->v6.sin6_family = AF_INET6;
381 SCTP_DEBUG_PRINTK("saddr: %pI6\n", &saddr->v6.sin6_addr); 374 ipv6_addr_copy(&saddr->v6.sin6_addr, &fl6->saddr);
382 } else {
383 pr_err("%s: asoc:%p Could not find a valid source "
384 "address for the dest:%pI6\n",
385 __func__, asoc, &daddr->v6.sin6_addr);
386 } 375 }
387
388 rcu_read_unlock();
389} 376}
390 377
391/* Make a copy of all potential local addresses. */ 378/* Make a copy of all potential local addresses. */
@@ -507,14 +494,13 @@ static int sctp_v6_to_addr_param(const union sctp_addr *addr,
507 return length; 494 return length;
508} 495}
509 496
510/* Initialize a sctp_addr from a dst_entry. */ 497/* Initialize a sctp_addr from struct in6_addr. */
511static void sctp_v6_dst_saddr(union sctp_addr *addr, struct dst_entry *dst, 498static void sctp_v6_to_addr(union sctp_addr *addr, struct in6_addr *saddr,
512 __be16 port) 499 __be16 port)
513{ 500{
514 struct rt6_info *rt = (struct rt6_info *)dst;
515 addr->sa.sa_family = AF_INET6; 501 addr->sa.sa_family = AF_INET6;
516 addr->v6.sin6_port = port; 502 addr->v6.sin6_port = port;
517 ipv6_addr_copy(&addr->v6.sin6_addr, &rt->rt6i_src.addr); 503 ipv6_addr_copy(&addr->v6.sin6_addr, saddr);
518} 504}
519 505
520/* Compare addresses exactly. 506/* Compare addresses exactly.
@@ -1001,7 +987,6 @@ static struct sctp_af sctp_af_inet6 = {
1001 .to_sk_daddr = sctp_v6_to_sk_daddr, 987 .to_sk_daddr = sctp_v6_to_sk_daddr,
1002 .from_addr_param = sctp_v6_from_addr_param, 988 .from_addr_param = sctp_v6_from_addr_param,
1003 .to_addr_param = sctp_v6_to_addr_param, 989 .to_addr_param = sctp_v6_to_addr_param,
1004 .dst_saddr = sctp_v6_dst_saddr,
1005 .cmp_addr = sctp_v6_cmp_addr, 990 .cmp_addr = sctp_v6_cmp_addr,
1006 .scope = sctp_v6_scope, 991 .scope = sctp_v6_scope,
1007 .addr_valid = sctp_v6_addr_valid, 992 .addr_valid = sctp_v6_addr_valid,
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index d5bf91d04f63..34216458ded1 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -465,33 +465,35 @@ static sctp_scope_t sctp_v4_scope(union sctp_addr *addr)
465 */ 465 */
466static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc, 466static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
467 union sctp_addr *daddr, 467 union sctp_addr *daddr,
468 union sctp_addr *saddr) 468 union sctp_addr *saddr,
469 struct flowi *fl,
470 struct sock *sk)
469{ 471{
470 struct rtable *rt; 472 struct rtable *rt;
471 struct flowi4 fl4; 473 struct flowi4 *fl4 = &fl->u.ip4;
472 struct sctp_bind_addr *bp; 474 struct sctp_bind_addr *bp;
473 struct sctp_sockaddr_entry *laddr; 475 struct sctp_sockaddr_entry *laddr;
474 struct dst_entry *dst = NULL; 476 struct dst_entry *dst = NULL;
475 union sctp_addr dst_saddr; 477 union sctp_addr dst_saddr;
476 478
477 memset(&fl4, 0x0, sizeof(struct flowi4)); 479 memset(fl4, 0x0, sizeof(struct flowi4));
478 fl4.daddr = daddr->v4.sin_addr.s_addr; 480 fl4->daddr = daddr->v4.sin_addr.s_addr;
479 fl4.fl4_dport = daddr->v4.sin_port; 481 fl4->fl4_dport = daddr->v4.sin_port;
480 fl4.flowi4_proto = IPPROTO_SCTP; 482 fl4->flowi4_proto = IPPROTO_SCTP;
481 if (asoc) { 483 if (asoc) {
482 fl4.flowi4_tos = RT_CONN_FLAGS(asoc->base.sk); 484 fl4->flowi4_tos = RT_CONN_FLAGS(asoc->base.sk);
483 fl4.flowi4_oif = asoc->base.sk->sk_bound_dev_if; 485 fl4->flowi4_oif = asoc->base.sk->sk_bound_dev_if;
484 fl4.fl4_sport = htons(asoc->base.bind_addr.port); 486 fl4->fl4_sport = htons(asoc->base.bind_addr.port);
485 } 487 }
486 if (saddr) { 488 if (saddr) {
487 fl4.saddr = saddr->v4.sin_addr.s_addr; 489 fl4->saddr = saddr->v4.sin_addr.s_addr;
488 fl4.fl4_sport = saddr->v4.sin_port; 490 fl4->fl4_sport = saddr->v4.sin_port;
489 } 491 }
490 492
491 SCTP_DEBUG_PRINTK("%s: DST:%pI4, SRC:%pI4 - ", 493 SCTP_DEBUG_PRINTK("%s: DST:%pI4, SRC:%pI4 - ",
492 __func__, &fl4.daddr, &fl4.saddr); 494 __func__, &fl4->daddr, &fl4->saddr);
493 495
494 rt = ip_route_output_key(&init_net, &fl4); 496 rt = ip_route_output_key(&init_net, fl4);
495 if (!IS_ERR(rt)) 497 if (!IS_ERR(rt))
496 dst = &rt->dst; 498 dst = &rt->dst;
497 499
@@ -533,9 +535,9 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
533 continue; 535 continue;
534 if ((laddr->state == SCTP_ADDR_SRC) && 536 if ((laddr->state == SCTP_ADDR_SRC) &&
535 (AF_INET == laddr->a.sa.sa_family)) { 537 (AF_INET == laddr->a.sa.sa_family)) {
536 fl4.saddr = laddr->a.v4.sin_addr.s_addr; 538 fl4->saddr = laddr->a.v4.sin_addr.s_addr;
537 fl4.fl4_sport = laddr->a.v4.sin_port; 539 fl4->fl4_sport = laddr->a.v4.sin_port;
538 rt = ip_route_output_key(&init_net, &fl4); 540 rt = ip_route_output_key(&init_net, fl4);
539 if (!IS_ERR(rt)) { 541 if (!IS_ERR(rt)) {
540 dst = &rt->dst; 542 dst = &rt->dst;
541 goto out_unlock; 543 goto out_unlock;
@@ -559,19 +561,15 @@ out:
559 * to cache it separately and hence this is an empty routine. 561 * to cache it separately and hence this is an empty routine.
560 */ 562 */
561static void sctp_v4_get_saddr(struct sctp_sock *sk, 563static void sctp_v4_get_saddr(struct sctp_sock *sk,
562 struct sctp_association *asoc, 564 struct sctp_transport *t,
563 struct dst_entry *dst,
564 union sctp_addr *daddr, 565 union sctp_addr *daddr,
565 union sctp_addr *saddr) 566 struct flowi *fl)
566{ 567{
567 struct rtable *rt = (struct rtable *)dst; 568 union sctp_addr *saddr = &t->saddr;
568 569 struct rtable *rt = (struct rtable *)t->dst;
569 if (!asoc)
570 return;
571 570
572 if (rt) { 571 if (rt) {
573 saddr->v4.sin_family = AF_INET; 572 saddr->v4.sin_family = AF_INET;
574 saddr->v4.sin_port = htons(asoc->base.bind_addr.port);
575 saddr->v4.sin_addr.s_addr = rt->rt_src; 573 saddr->v4.sin_addr.s_addr = rt->rt_src;
576 } 574 }
577} 575}
@@ -950,7 +948,6 @@ static struct sctp_af sctp_af_inet = {
950 .to_sk_daddr = sctp_v4_to_sk_daddr, 948 .to_sk_daddr = sctp_v4_to_sk_daddr,
951 .from_addr_param = sctp_v4_from_addr_param, 949 .from_addr_param = sctp_v4_from_addr_param,
952 .to_addr_param = sctp_v4_to_addr_param, 950 .to_addr_param = sctp_v4_to_addr_param,
953 .dst_saddr = sctp_v4_dst_saddr,
954 .cmp_addr = sctp_v4_cmp_addr, 951 .cmp_addr = sctp_v4_cmp_addr,
955 .addr_valid = sctp_v4_addr_valid, 952 .addr_valid = sctp_v4_addr_valid,
956 .inaddr_any = sctp_v4_inaddr_any, 953 .inaddr_any = sctp_v4_inaddr_any,
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index f694ee116746..33d9ee629b4e 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2287,7 +2287,7 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,
2287 trans->param_flags = 2287 trans->param_flags =
2288 (trans->param_flags & ~SPP_PMTUD) | pmtud_change; 2288 (trans->param_flags & ~SPP_PMTUD) | pmtud_change;
2289 if (update) { 2289 if (update) {
2290 sctp_transport_pmtu(trans); 2290 sctp_transport_pmtu(trans, sctp_opt2sk(sp));
2291 sctp_assoc_sync_pmtu(asoc); 2291 sctp_assoc_sync_pmtu(asoc);
2292 } 2292 }
2293 } else if (asoc) { 2293 } else if (asoc) {
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index d3ae493d234a..2544b9b21f86 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -211,11 +211,15 @@ void sctp_transport_set_owner(struct sctp_transport *transport,
211} 211}
212 212
213/* Initialize the pmtu of a transport. */ 213/* Initialize the pmtu of a transport. */
214void sctp_transport_pmtu(struct sctp_transport *transport) 214void sctp_transport_pmtu(struct sctp_transport *transport, struct sock *sk)
215{ 215{
216 struct dst_entry *dst; 216 struct dst_entry *dst;
217 struct flowi fl;
217 218
218 dst = transport->af_specific->get_dst(NULL, &transport->ipaddr, NULL); 219 dst = transport->af_specific->get_dst(transport->asoc,
220 &transport->ipaddr,
221 &transport->saddr,
222 &fl, sk);
219 223
220 if (dst) { 224 if (dst) {
221 transport->pathmtu = dst_mtu(dst); 225 transport->pathmtu = dst_mtu(dst);
@@ -272,15 +276,16 @@ void sctp_transport_route(struct sctp_transport *transport,
272 struct sctp_af *af = transport->af_specific; 276 struct sctp_af *af = transport->af_specific;
273 union sctp_addr *daddr = &transport->ipaddr; 277 union sctp_addr *daddr = &transport->ipaddr;
274 struct dst_entry *dst; 278 struct dst_entry *dst;
279 struct flowi fl;
275 280
276 dst = af->get_dst(asoc, daddr, saddr); 281 dst = af->get_dst(asoc, daddr, saddr, &fl, sctp_opt2sk(opt));
282 transport->dst = dst;
277 283
278 if (saddr) 284 if (saddr)
279 memcpy(&transport->saddr, saddr, sizeof(union sctp_addr)); 285 memcpy(&transport->saddr, saddr, sizeof(union sctp_addr));
280 else 286 else
281 af->get_saddr(opt, asoc, dst, daddr, &transport->saddr); 287 af->get_saddr(opt, transport, daddr, &fl);
282 288
283 transport->dst = dst;
284 if ((transport->param_flags & SPP_PMTUD_DISABLE) && transport->pathmtu) { 289 if ((transport->param_flags & SPP_PMTUD_DISABLE) && transport->pathmtu) {
285 return; 290 return;
286 } 291 }