diff options
Diffstat (limited to 'net/sctp/protocol.c')
-rw-r--r-- | net/sctp/protocol.c | 47 |
1 files changed, 22 insertions, 25 deletions
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 | */ |
466 | static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc, | 466 | static 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 | */ |
561 | static void sctp_v4_get_saddr(struct sctp_sock *sk, | 563 | static 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, |