diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-21 00:43:21 +0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-21 00:43:21 +0400 |
commit | 06f4e926d256d902dd9a53dcb400fd74974ce087 (patch) | |
tree | 0b438b67f5f0eff6fd617bc497a9dace6164a488 /net/sctp/protocol.c | |
parent | 8e7bfcbab3825d1b404d615cb1b54f44ff81f981 (diff) | |
parent | d93515611bbc70c2fe4db232e5feb448ed8e4cc9 (diff) | |
download | linux-06f4e926d256d902dd9a53dcb400fd74974ce087.tar.xz |
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.c | 71 |
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, } /* Initialize a sctp_addr from a dst_entry. */ -static void sctp_v4_dst_saddr(union sctp_addr *saddr, struct dst_entry *dst, +static void sctp_v4_dst_saddr(union sctp_addr *saddr, struct flowi4 *fl4, __be16 port) { - struct rtable *rt = (struct rtable *)dst; saddr->v4.sin_family = AF_INET; saddr->v4.sin_port = port; - saddr->v4.sin_addr.s_addr = rt->rt_src; + saddr->v4.sin_addr.s_addr = fl4->saddr; } /* Compare two addresses exactly. */ @@ -456,35 +455,36 @@ static sctp_scope_t sctp_v4_scope(union sctp_addr *addr) * addresses. If an association is passed, trys to get a dst entry with a * source address that matches an address in the bind address list. */ -static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc, - union sctp_addr *daddr, - union sctp_addr *saddr) +static void sctp_v4_get_dst(struct sctp_transport *t, union sctp_addr *saddr, + struct flowi *fl, struct sock *sk) { + struct sctp_association *asoc = t->asoc; struct rtable *rt; - struct flowi4 fl4; + struct flowi4 *fl4 = &fl->u.ip4; struct sctp_bind_addr *bp; struct sctp_sockaddr_entry *laddr; struct dst_entry *dst = NULL; + union sctp_addr *daddr = &t->ipaddr; union sctp_addr dst_saddr; - memset(&fl4, 0x0, sizeof(struct flowi4)); - fl4.daddr = daddr->v4.sin_addr.s_addr; - fl4.fl4_dport = daddr->v4.sin_port; - fl4.flowi4_proto = IPPROTO_SCTP; + memset(fl4, 0x0, sizeof(struct flowi4)); + fl4->daddr = daddr->v4.sin_addr.s_addr; + fl4->fl4_dport = daddr->v4.sin_port; + fl4->flowi4_proto = IPPROTO_SCTP; if (asoc) { - fl4.flowi4_tos = RT_CONN_FLAGS(asoc->base.sk); - fl4.flowi4_oif = asoc->base.sk->sk_bound_dev_if; - fl4.fl4_sport = htons(asoc->base.bind_addr.port); + fl4->flowi4_tos = RT_CONN_FLAGS(asoc->base.sk); + fl4->flowi4_oif = asoc->base.sk->sk_bound_dev_if; + fl4->fl4_sport = htons(asoc->base.bind_addr.port); } if (saddr) { - fl4.saddr = saddr->v4.sin_addr.s_addr; - fl4.fl4_sport = saddr->v4.sin_port; + fl4->saddr = saddr->v4.sin_addr.s_addr; + fl4->fl4_sport = saddr->v4.sin_port; } SCTP_DEBUG_PRINTK("%s: DST:%pI4, SRC:%pI4 - ", - __func__, &fl4.daddr, &fl4.saddr); + __func__, &fl4->daddr, &fl4->saddr); - rt = ip_route_output_key(&init_net, &fl4); + rt = ip_route_output_key(&init_net, fl4); if (!IS_ERR(rt)) dst = &rt->dst; @@ -500,7 +500,7 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc, /* Walk through the bind address list and look for a bind * address that matches the source address of the returned dst. */ - sctp_v4_dst_saddr(&dst_saddr, dst, htons(bp->port)); + sctp_v4_dst_saddr(&dst_saddr, fl4, htons(bp->port)); rcu_read_lock(); list_for_each_entry_rcu(laddr, &bp->address_list, list) { if (!laddr->valid || (laddr->state != SCTP_ADDR_SRC)) @@ -526,9 +526,9 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc, continue; if ((laddr->state == SCTP_ADDR_SRC) && (AF_INET == laddr->a.sa.sa_family)) { - fl4.saddr = laddr->a.v4.sin_addr.s_addr; - fl4.fl4_sport = laddr->a.v4.sin_port; - rt = ip_route_output_key(&init_net, &fl4); + fl4->saddr = laddr->a.v4.sin_addr.s_addr; + fl4->fl4_sport = laddr->a.v4.sin_port; + rt = ip_route_output_key(&init_net, fl4); if (!IS_ERR(rt)) { dst = &rt->dst; goto out_unlock; @@ -539,33 +539,27 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc, out_unlock: rcu_read_unlock(); out: + t->dst = dst; if (dst) SCTP_DEBUG_PRINTK("rt_dst:%pI4, rt_src:%pI4\n", - &rt->rt_dst, &rt->rt_src); + &fl4->daddr, &fl4->saddr); else SCTP_DEBUG_PRINTK("NO ROUTE\n"); - - return dst; } /* For v4, the source address is cached in the route entry(dst). So no need * to cache it separately and hence this is an empty routine. */ static void sctp_v4_get_saddr(struct sctp_sock *sk, - struct sctp_association *asoc, - struct dst_entry *dst, - union sctp_addr *daddr, - union sctp_addr *saddr) + struct sctp_transport *t, + struct flowi *fl) { - struct rtable *rt = (struct rtable *)dst; - - if (!asoc) - return; + union sctp_addr *saddr = &t->saddr; + struct rtable *rt = (struct rtable *)t->dst; if (rt) { saddr->v4.sin_family = AF_INET; - saddr->v4.sin_port = htons(asoc->base.bind_addr.port); - saddr->v4.sin_addr.s_addr = rt->rt_src; + saddr->v4.sin_addr.s_addr = fl->u.ip4.saddr; } } @@ -847,14 +841,14 @@ static inline int sctp_v4_xmit(struct sk_buff *skb, SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, src:%pI4, dst:%pI4\n", __func__, skb, skb->len, - &skb_rtable(skb)->rt_src, - &skb_rtable(skb)->rt_dst); + &transport->fl.u.ip4.saddr, + &transport->fl.u.ip4.daddr); inet->pmtudisc = transport->param_flags & SPP_PMTUD_ENABLE ? IP_PMTUDISC_DO : IP_PMTUDISC_DONT; SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS); - return ip_queue_xmit(skb); + return ip_queue_xmit(skb, &transport->fl); } static struct sctp_af sctp_af_inet; @@ -943,7 +937,6 @@ static struct sctp_af sctp_af_inet = { .to_sk_daddr = sctp_v4_to_sk_daddr, .from_addr_param = sctp_v4_from_addr_param, .to_addr_param = sctp_v4_to_addr_param, - .dst_saddr = sctp_v4_dst_saddr, .cmp_addr = sctp_v4_cmp_addr, .addr_valid = sctp_v4_addr_valid, .inaddr_any = sctp_v4_inaddr_any, |