aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVlad Yasevich <vladislav.yasevich@hp.com>2011-04-26 17:54:17 -0400
committerDavid S. Miller <davem@davemloft.net>2011-04-27 16:14:06 -0400
commitda0420bee24a1ba54e55a61e95b1a53205d7e62d (patch)
treeb17401ad5e6d97f8e3c8649725d5ca0a20e1b765
parentaf1384703f8a4ff3d245925d6596ef1c5c6e469e (diff)
sctp: clean up route lookup calls
Change the call to take the transport parameter and set the cached 'dst' appropriately inside the get_dst() function calls. This will allow us in the future to clean up source address storage as well. 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>
-rw-r--r--include/net/sctp/structs.h3
-rw-r--r--net/sctp/ipv6.c17
-rw-r--r--net/sctp/protocol.c12
-rw-r--r--net/sctp/transport.c23
4 files changed, 24 insertions, 31 deletions
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index bb2f43b7e9a8..ff3e8cce7d66 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -564,8 +564,7 @@ struct sctp_af {
564 int optname, 564 int optname,
565 char __user *optval, 565 char __user *optval,
566 int __user *optlen); 566 int __user *optlen);
567 struct dst_entry *(*get_dst) (struct sctp_association *asoc, 567 void (*get_dst) (struct sctp_transport *t,
568 union sctp_addr *daddr,
569 union sctp_addr *saddr, 568 union sctp_addr *saddr,
570 struct flowi *fl, 569 struct flowi *fl,
571 struct sock *sk); 570 struct sock *sk);
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index a1913a4b6f3a..500875f4dc41 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -247,17 +247,16 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport)
247/* Returns the dst cache entry for the given source and destination ip 247/* Returns the dst cache entry for the given source and destination ip
248 * addresses. 248 * addresses.
249 */ 249 */
250static struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc, 250static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
251 union sctp_addr *daddr, 251 struct flowi *fl, struct sock *sk)
252 union sctp_addr *saddr,
253 struct flowi *fl,
254 struct sock *sk)
255{ 252{
253 struct sctp_association *asoc = t->asoc;
256 struct dst_entry *dst = NULL; 254 struct dst_entry *dst = NULL;
257 struct flowi6 *fl6 = &fl->u.ip6; 255 struct flowi6 *fl6 = &fl->u.ip6;
258 struct sctp_bind_addr *bp; 256 struct sctp_bind_addr *bp;
259 struct sctp_sockaddr_entry *laddr; 257 struct sctp_sockaddr_entry *laddr;
260 union sctp_addr *baddr = NULL; 258 union sctp_addr *baddr = NULL;
259 union sctp_addr *daddr = &t->ipaddr;
261 union sctp_addr dst_saddr; 260 union sctp_addr dst_saddr;
262 __u8 matchlen = 0; 261 __u8 matchlen = 0;
263 __u8 bmatchlen; 262 __u8 bmatchlen;
@@ -270,7 +269,6 @@ static struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc,
270 if (ipv6_addr_type(&daddr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) 269 if (ipv6_addr_type(&daddr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL)
271 fl6->flowi6_oif = daddr->v6.sin6_scope_id; 270 fl6->flowi6_oif = daddr->v6.sin6_scope_id;
272 271
273
274 SCTP_DEBUG_PRINTK("%s: DST=%pI6 ", __func__, &fl6->daddr); 272 SCTP_DEBUG_PRINTK("%s: DST=%pI6 ", __func__, &fl6->daddr);
275 273
276 if (asoc) 274 if (asoc)
@@ -343,12 +341,13 @@ out:
343 if (!IS_ERR(dst)) { 341 if (!IS_ERR(dst)) {
344 struct rt6_info *rt; 342 struct rt6_info *rt;
345 rt = (struct rt6_info *)dst; 343 rt = (struct rt6_info *)dst;
344 t->dst = dst;
346 SCTP_DEBUG_PRINTK("rt6_dst:%pI6 rt6_src:%pI6\n", 345 SCTP_DEBUG_PRINTK("rt6_dst:%pI6 rt6_src:%pI6\n",
347 &rt->rt6i_dst.addr, &fl6->saddr); 346 &rt->rt6i_dst.addr, &fl6->saddr);
348 return dst; 347 } else {
348 t->dst = NULL;
349 SCTP_DEBUG_PRINTK("NO ROUTE\n");
349 } 350 }
350 SCTP_DEBUG_PRINTK("NO ROUTE\n");
351 return NULL;
352} 351}
353 352
354/* Returns the number of consecutive initial bits that match in the 2 ipv6 353/* Returns the number of consecutive initial bits that match in the 2 ipv6
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 68b4c4317d61..9d3f15957d12 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -463,17 +463,16 @@ static sctp_scope_t sctp_v4_scope(union sctp_addr *addr)
463 * addresses. If an association is passed, trys to get a dst entry with a 463 * addresses. If an association is passed, trys to get a dst entry with a
464 * source address that matches an address in the bind address list. 464 * source address that matches an address in the bind address list.
465 */ 465 */
466static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc, 466static void sctp_v4_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
467 union sctp_addr *daddr, 467 struct flowi *fl, struct sock *sk)
468 union sctp_addr *saddr,
469 struct flowi *fl,
470 struct sock *sk)
471{ 468{
469 struct sctp_association *asoc = t->asoc;
472 struct rtable *rt; 470 struct rtable *rt;
473 struct flowi4 *fl4 = &fl->u.ip4; 471 struct flowi4 *fl4 = &fl->u.ip4;
474 struct sctp_bind_addr *bp; 472 struct sctp_bind_addr *bp;
475 struct sctp_sockaddr_entry *laddr; 473 struct sctp_sockaddr_entry *laddr;
476 struct dst_entry *dst = NULL; 474 struct dst_entry *dst = NULL;
475 union sctp_addr *daddr = &t->ipaddr;
477 union sctp_addr dst_saddr; 476 union sctp_addr dst_saddr;
478 477
479 memset(fl4, 0x0, sizeof(struct flowi4)); 478 memset(fl4, 0x0, sizeof(struct flowi4));
@@ -548,13 +547,12 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
548out_unlock: 547out_unlock:
549 rcu_read_unlock(); 548 rcu_read_unlock();
550out: 549out:
550 t->dst = dst;
551 if (dst) 551 if (dst)
552 SCTP_DEBUG_PRINTK("rt_dst:%pI4, rt_src:%pI4\n", 552 SCTP_DEBUG_PRINTK("rt_dst:%pI4, rt_src:%pI4\n",
553 &rt->rt_dst, &rt->rt_src); 553 &rt->rt_dst, &rt->rt_src);
554 else 554 else
555 SCTP_DEBUG_PRINTK("NO ROUTE\n"); 555 SCTP_DEBUG_PRINTK("NO ROUTE\n");
556
557 return dst;
558} 556}
559 557
560/* For v4, the source address is cached in the route entry(dst). So no need 558/* For v4, the source address is cached in the route entry(dst). So no need
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index 1fbb920f8dfb..d8595dd1a8a7 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -213,17 +213,17 @@ void sctp_transport_set_owner(struct sctp_transport *transport,
213/* Initialize the pmtu of a transport. */ 213/* Initialize the pmtu of a transport. */
214void sctp_transport_pmtu(struct sctp_transport *transport, struct sock *sk) 214void sctp_transport_pmtu(struct sctp_transport *transport, struct sock *sk)
215{ 215{
216 struct dst_entry *dst;
217 struct flowi fl; 216 struct flowi fl;
218 217
219 dst = transport->af_specific->get_dst(transport->asoc, 218 /* If we don't have a fresh route, look one up */
220 &transport->ipaddr, 219 if (!transport->dst || transport->dst->obsolete > 1) {
221 &transport->saddr, 220 dst_release(transport->dst);
221 transport->af_specific->get_dst(transport, &transport->saddr,
222 &fl, sk); 222 &fl, sk);
223 }
223 224
224 if (dst) { 225 if (transport->dst) {
225 transport->pathmtu = dst_mtu(dst); 226 transport->pathmtu = dst_mtu(transport->dst);
226 dst_release(dst);
227 } else 227 } else
228 transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT; 228 transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT;
229} 229}
@@ -274,12 +274,9 @@ void sctp_transport_route(struct sctp_transport *transport,
274{ 274{
275 struct sctp_association *asoc = transport->asoc; 275 struct sctp_association *asoc = transport->asoc;
276 struct sctp_af *af = transport->af_specific; 276 struct sctp_af *af = transport->af_specific;
277 union sctp_addr *daddr = &transport->ipaddr;
278 struct dst_entry *dst;
279 struct flowi fl; 277 struct flowi fl;
280 278
281 dst = af->get_dst(asoc, daddr, saddr, &fl, sctp_opt2sk(opt)); 279 af->get_dst(transport, saddr, &fl, sctp_opt2sk(opt));
282 transport->dst = dst;
283 280
284 if (saddr) 281 if (saddr)
285 memcpy(&transport->saddr, saddr, sizeof(union sctp_addr)); 282 memcpy(&transport->saddr, saddr, sizeof(union sctp_addr));
@@ -289,8 +286,8 @@ void sctp_transport_route(struct sctp_transport *transport,
289 if ((transport->param_flags & SPP_PMTUD_DISABLE) && transport->pathmtu) { 286 if ((transport->param_flags & SPP_PMTUD_DISABLE) && transport->pathmtu) {
290 return; 287 return;
291 } 288 }
292 if (dst) { 289 if (transport->dst) {
293 transport->pathmtu = dst_mtu(dst); 290 transport->pathmtu = dst_mtu(transport->dst);
294 291
295 /* Initialize sk->sk_rcv_saddr, if the transport is the 292 /* Initialize sk->sk_rcv_saddr, if the transport is the
296 * association's active path for getsockname(). 293 * association's active path for getsockname().