aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/protocol.c
diff options
context:
space:
mode:
authorVlad Yasevich <vladislav.yasevich@hp.com>2011-04-26 17:51:31 -0400
committerDavid S. Miller <davem@davemloft.net>2011-04-27 16:14:04 -0400
commit9914ae3ca770389a3bec3114d0a07532a7f235dd (patch)
tree269120740aa1afdb0dd792284341aaee93024f28 /net/sctp/protocol.c
parent625034113bd45c71fb9e329f52f25fef9e6993a3 (diff)
sctp: cache the ipv6 source after route lookup
The ipv6 routing lookup does give us a source address, but instead of filling it into the dst, it's stored in the flowi. We can use that instead of going through the entire source address selection again. Also the useless ->dst_saddr member of sctp_pf is removed. And sctp_v6_dst_saddr() is removed, instead by introduce sctp_v6_to_addr(), which can be reused to cleanup some dup code. Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com> Signed-off-by: Wei Yongjun <yjwei@cn.fujitsu.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/protocol.c')
-rw-r--r--net/sctp/protocol.c47
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 */
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,