aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/protocol.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-05-20 16:43:21 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-20 16:43:21 -0400
commit06f4e926d256d902dd9a53dcb400fd74974ce087 (patch)
tree0b438b67f5f0eff6fd617bc497a9dace6164a488 /net/sctp/protocol.c
parent8e7bfcbab3825d1b404d615cb1b54f44ff81f981 (diff)
parentd93515611bbc70c2fe4db232e5feb448ed8e4cc9 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1446 commits) macvlan: fix panic if lowerdev in a bond tg3: Add braces around 5906 workaround. tg3: Fix NETIF_F_LOOPBACK error macvlan: remove one synchronize_rcu() call networking: NET_CLS_ROUTE4 depends on INET irda: Fix error propagation in ircomm_lmp_connect_response() irda: Kill set but unused variable 'bytes' in irlan_check_command_param() irda: Kill set but unused variable 'clen' in ircomm_connect_indication() rxrpc: Fix set but unused variable 'usage' in rxrpc_get_transport() be2net: Kill set but unused variable 'req' in lancer_fw_download() irda: Kill set but unused vars 'saddr' and 'daddr' in irlan_provider_connect_indication() atl1c: atl1c_resume() is only used when CONFIG_PM_SLEEP is defined. rxrpc: Fix set but unused variable 'usage' in rxrpc_get_peer(). rxrpc: Kill set but unused variable 'local' in rxrpc_UDP_error_handler() rxrpc: Kill set but unused variable 'sp' in rxrpc_process_connection() rxrpc: Kill set but unused variable 'sp' in rxrpc_rotate_tx_window() pkt_sched: Kill set but unused variable 'protocol' in tc_classify() isdn: capi: Use pr_debug() instead of ifdefs. tg3: Update version to 3.119 tg3: Apply rx_discards fix to 5719/5720 ... Fix up trivial conflicts in arch/x86/Kconfig and net/mac80211/agg-tx.c as per Davem.
Diffstat (limited to 'net/sctp/protocol.c')
-rw-r--r--net/sctp/protocol.c71
1 files changed, 32 insertions, 39 deletions
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 065d99958ced..67380a29e2e9 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -332,13 +332,12 @@ static int sctp_v4_to_addr_param(const union sctp_addr *addr,
332} 332}
333 333
334/* Initialize a sctp_addr from a dst_entry. */ 334/* Initialize a sctp_addr from a dst_entry. */
335static void sctp_v4_dst_saddr(union sctp_addr *saddr, struct dst_entry *dst, 335static void sctp_v4_dst_saddr(union sctp_addr *saddr, struct flowi4 *fl4,
336 __be16 port) 336 __be16 port)
337{ 337{
338 struct rtable *rt = (struct rtable *)dst;
339 saddr->v4.sin_family = AF_INET; 338 saddr->v4.sin_family = AF_INET;
340 saddr->v4.sin_port = port; 339 saddr->v4.sin_port = port;
341 saddr->v4.sin_addr.s_addr = rt->rt_src; 340 saddr->v4.sin_addr.s_addr = fl4->saddr;
342} 341}
343 342
344/* Compare two addresses exactly. */ 343/* Compare two addresses exactly. */
@@ -456,35 +455,36 @@ static sctp_scope_t sctp_v4_scope(union sctp_addr *addr)
456 * addresses. If an association is passed, trys to get a dst entry with a 455 * addresses. If an association is passed, trys to get a dst entry with a
457 * source address that matches an address in the bind address list. 456 * source address that matches an address in the bind address list.
458 */ 457 */
459static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc, 458static void sctp_v4_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
460 union sctp_addr *daddr, 459 struct flowi *fl, struct sock *sk)
461 union sctp_addr *saddr)
462{ 460{
461 struct sctp_association *asoc = t->asoc;
463 struct rtable *rt; 462 struct rtable *rt;
464 struct flowi4 fl4; 463 struct flowi4 *fl4 = &fl->u.ip4;
465 struct sctp_bind_addr *bp; 464 struct sctp_bind_addr *bp;
466 struct sctp_sockaddr_entry *laddr; 465 struct sctp_sockaddr_entry *laddr;
467 struct dst_entry *dst = NULL; 466 struct dst_entry *dst = NULL;
467 union sctp_addr *daddr = &t->ipaddr;
468 union sctp_addr dst_saddr; 468 union sctp_addr dst_saddr;
469 469
470 memset(&fl4, 0x0, sizeof(struct flowi4)); 470 memset(fl4, 0x0, sizeof(struct flowi4));
471 fl4.daddr = daddr->v4.sin_addr.s_addr; 471 fl4->daddr = daddr->v4.sin_addr.s_addr;
472 fl4.fl4_dport = daddr->v4.sin_port; 472 fl4->fl4_dport = daddr->v4.sin_port;
473 fl4.flowi4_proto = IPPROTO_SCTP; 473 fl4->flowi4_proto = IPPROTO_SCTP;
474 if (asoc) { 474 if (asoc) {
475 fl4.flowi4_tos = RT_CONN_FLAGS(asoc->base.sk); 475 fl4->flowi4_tos = RT_CONN_FLAGS(asoc->base.sk);
476 fl4.flowi4_oif = asoc->base.sk->sk_bound_dev_if; 476 fl4->flowi4_oif = asoc->base.sk->sk_bound_dev_if;
477 fl4.fl4_sport = htons(asoc->base.bind_addr.port); 477 fl4->fl4_sport = htons(asoc->base.bind_addr.port);
478 } 478 }
479 if (saddr) { 479 if (saddr) {
480 fl4.saddr = saddr->v4.sin_addr.s_addr; 480 fl4->saddr = saddr->v4.sin_addr.s_addr;
481 fl4.fl4_sport = saddr->v4.sin_port; 481 fl4->fl4_sport = saddr->v4.sin_port;
482 } 482 }
483 483
484 SCTP_DEBUG_PRINTK("%s: DST:%pI4, SRC:%pI4 - ", 484 SCTP_DEBUG_PRINTK("%s: DST:%pI4, SRC:%pI4 - ",
485 __func__, &fl4.daddr, &fl4.saddr); 485 __func__, &fl4->daddr, &fl4->saddr);
486 486
487 rt = ip_route_output_key(&init_net, &fl4); 487 rt = ip_route_output_key(&init_net, fl4);
488 if (!IS_ERR(rt)) 488 if (!IS_ERR(rt))
489 dst = &rt->dst; 489 dst = &rt->dst;
490 490
@@ -500,7 +500,7 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
500 /* Walk through the bind address list and look for a bind 500 /* Walk through the bind address list and look for a bind
501 * address that matches the source address of the returned dst. 501 * address that matches the source address of the returned dst.
502 */ 502 */
503 sctp_v4_dst_saddr(&dst_saddr, dst, htons(bp->port)); 503 sctp_v4_dst_saddr(&dst_saddr, fl4, htons(bp->port));
504 rcu_read_lock(); 504 rcu_read_lock();
505 list_for_each_entry_rcu(laddr, &bp->address_list, list) { 505 list_for_each_entry_rcu(laddr, &bp->address_list, list) {
506 if (!laddr->valid || (laddr->state != SCTP_ADDR_SRC)) 506 if (!laddr->valid || (laddr->state != SCTP_ADDR_SRC))
@@ -526,9 +526,9 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
526 continue; 526 continue;
527 if ((laddr->state == SCTP_ADDR_SRC) && 527 if ((laddr->state == SCTP_ADDR_SRC) &&
528 (AF_INET == laddr->a.sa.sa_family)) { 528 (AF_INET == laddr->a.sa.sa_family)) {
529 fl4.saddr = laddr->a.v4.sin_addr.s_addr; 529 fl4->saddr = laddr->a.v4.sin_addr.s_addr;
530 fl4.fl4_sport = laddr->a.v4.sin_port; 530 fl4->fl4_sport = laddr->a.v4.sin_port;
531 rt = ip_route_output_key(&init_net, &fl4); 531 rt = ip_route_output_key(&init_net, fl4);
532 if (!IS_ERR(rt)) { 532 if (!IS_ERR(rt)) {
533 dst = &rt->dst; 533 dst = &rt->dst;
534 goto out_unlock; 534 goto out_unlock;
@@ -539,33 +539,27 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
539out_unlock: 539out_unlock:
540 rcu_read_unlock(); 540 rcu_read_unlock();
541out: 541out:
542 t->dst = dst;
542 if (dst) 543 if (dst)
543 SCTP_DEBUG_PRINTK("rt_dst:%pI4, rt_src:%pI4\n", 544 SCTP_DEBUG_PRINTK("rt_dst:%pI4, rt_src:%pI4\n",
544 &rt->rt_dst, &rt->rt_src); 545 &fl4->daddr, &fl4->saddr);
545 else 546 else
546 SCTP_DEBUG_PRINTK("NO ROUTE\n"); 547 SCTP_DEBUG_PRINTK("NO ROUTE\n");
547
548 return dst;
549} 548}
550 549
551/* For v4, the source address is cached in the route entry(dst). So no need 550/* For v4, the source address is cached in the route entry(dst). So no need
552 * to cache it separately and hence this is an empty routine. 551 * to cache it separately and hence this is an empty routine.
553 */ 552 */
554static void sctp_v4_get_saddr(struct sctp_sock *sk, 553static void sctp_v4_get_saddr(struct sctp_sock *sk,
555 struct sctp_association *asoc, 554 struct sctp_transport *t,
556 struct dst_entry *dst, 555 struct flowi *fl)
557 union sctp_addr *daddr,
558 union sctp_addr *saddr)
559{ 556{
560 struct rtable *rt = (struct rtable *)dst; 557 union sctp_addr *saddr = &t->saddr;
561 558 struct rtable *rt = (struct rtable *)t->dst;
562 if (!asoc)
563 return;
564 559
565 if (rt) { 560 if (rt) {
566 saddr->v4.sin_family = AF_INET; 561 saddr->v4.sin_family = AF_INET;
567 saddr->v4.sin_port = htons(asoc->base.bind_addr.port); 562 saddr->v4.sin_addr.s_addr = fl->u.ip4.saddr;
568 saddr->v4.sin_addr.s_addr = rt->rt_src;
569 } 563 }
570} 564}
571 565
@@ -847,14 +841,14 @@ static inline int sctp_v4_xmit(struct sk_buff *skb,
847 841
848 SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, src:%pI4, dst:%pI4\n", 842 SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, src:%pI4, dst:%pI4\n",
849 __func__, skb, skb->len, 843 __func__, skb, skb->len,
850 &skb_rtable(skb)->rt_src, 844 &transport->fl.u.ip4.saddr,
851 &skb_rtable(skb)->rt_dst); 845 &transport->fl.u.ip4.daddr);
852 846
853 inet->pmtudisc = transport->param_flags & SPP_PMTUD_ENABLE ? 847 inet->pmtudisc = transport->param_flags & SPP_PMTUD_ENABLE ?
854 IP_PMTUDISC_DO : IP_PMTUDISC_DONT; 848 IP_PMTUDISC_DO : IP_PMTUDISC_DONT;
855 849
856 SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS); 850 SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS);
857 return ip_queue_xmit(skb); 851 return ip_queue_xmit(skb, &transport->fl);
858} 852}
859 853
860static struct sctp_af sctp_af_inet; 854static struct sctp_af sctp_af_inet;
@@ -943,7 +937,6 @@ static struct sctp_af sctp_af_inet = {
943 .to_sk_daddr = sctp_v4_to_sk_daddr, 937 .to_sk_daddr = sctp_v4_to_sk_daddr,
944 .from_addr_param = sctp_v4_from_addr_param, 938 .from_addr_param = sctp_v4_from_addr_param,
945 .to_addr_param = sctp_v4_to_addr_param, 939 .to_addr_param = sctp_v4_to_addr_param,
946 .dst_saddr = sctp_v4_dst_saddr,
947 .cmp_addr = sctp_v4_cmp_addr, 940 .cmp_addr = sctp_v4_cmp_addr,
948 .addr_valid = sctp_v4_addr_valid, 941 .addr_valid = sctp_v4_addr_valid,
949 .inaddr_any = sctp_v4_inaddr_any, 942 .inaddr_any = sctp_v4_inaddr_any,