aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2007-06-14 16:06:21 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-06-14 16:06:21 -0400
commit559f0a2857f1d1a93c4f398d2775e228fdb8b8ce (patch)
treeab30bcb58b49c17aa40942ebfb446a8e3a26deac
parent74235a25c673f80147c1f975304888e8212a14d5 (diff)
parent06ad391919b2078ec2e012f0593014b88e7a6c4e (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/vxy/lksctp-dev
-rw-r--r--include/net/sctp/sctp.h7
-rw-r--r--include/net/sctp/structs.h7
-rw-r--r--net/sctp/associola.c4
-rw-r--r--net/sctp/input.c24
-rw-r--r--net/sctp/socket.c31
-rw-r--r--net/sctp/transport.c39
6 files changed, 88 insertions, 24 deletions
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index dda72bf5b9b4..16baef4dab7e 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -503,6 +503,13 @@ static inline int sctp_frag_point(const struct sctp_sock *sp, int pmtu)
503 return frag; 503 return frag;
504} 504}
505 505
506static inline void sctp_assoc_pending_pmtu(struct sctp_association *asoc)
507{
508
509 sctp_assoc_sync_pmtu(asoc);
510 asoc->pmtu_pending = 0;
511}
512
506/* Walk through a list of TLV parameters. Don't trust the 513/* Walk through a list of TLV parameters. Don't trust the
507 * individual parameter lengths and instead depend on 514 * individual parameter lengths and instead depend on
508 * the chunk length to indicate when to stop. Make sure 515 * the chunk length to indicate when to stop. Make sure
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 5e81984b8478..ee4559b11302 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -912,6 +912,9 @@ struct sctp_transport {
912 */ 912 */
913 __u16 pathmaxrxt; 913 __u16 pathmaxrxt;
914 914
915 /* is the Path MTU update pending on this tranport */
916 __u8 pmtu_pending;
917
915 /* PMTU : The current known path MTU. */ 918 /* PMTU : The current known path MTU. */
916 __u32 pathmtu; 919 __u32 pathmtu;
917 920
@@ -1006,6 +1009,7 @@ void sctp_transport_raise_cwnd(struct sctp_transport *, __u32, __u32);
1006void sctp_transport_lower_cwnd(struct sctp_transport *, sctp_lower_cwnd_t); 1009void sctp_transport_lower_cwnd(struct sctp_transport *, sctp_lower_cwnd_t);
1007unsigned long sctp_transport_timeout(struct sctp_transport *); 1010unsigned long sctp_transport_timeout(struct sctp_transport *);
1008void sctp_transport_reset(struct sctp_transport *); 1011void sctp_transport_reset(struct sctp_transport *);
1012void sctp_transport_update_pmtu(struct sctp_transport *, u32);
1009 1013
1010 1014
1011/* This is the structure we use to queue packets as they come into 1015/* This is the structure we use to queue packets as they come into
@@ -1565,6 +1569,9 @@ struct sctp_association {
1565 */ 1569 */
1566 __u16 pathmaxrxt; 1570 __u16 pathmaxrxt;
1567 1571
1572 /* Flag that path mtu update is pending */
1573 __u8 pmtu_pending;
1574
1568 /* Association : The smallest PMTU discovered for all of the 1575 /* Association : The smallest PMTU discovered for all of the
1569 * PMTU : peer's transport addresses. 1576 * PMTU : peer's transport addresses.
1570 */ 1577 */
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index df94e3cdfba3..498edb0cd4e5 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -1231,6 +1231,10 @@ void sctp_assoc_sync_pmtu(struct sctp_association *asoc)
1231 /* Get the lowest pmtu of all the transports. */ 1231 /* Get the lowest pmtu of all the transports. */
1232 list_for_each(pos, &asoc->peer.transport_addr_list) { 1232 list_for_each(pos, &asoc->peer.transport_addr_list) {
1233 t = list_entry(pos, struct sctp_transport, transports); 1233 t = list_entry(pos, struct sctp_transport, transports);
1234 if (t->pmtu_pending && t->dst) {
1235 sctp_transport_update_pmtu(t, dst_mtu(t->dst));
1236 t->pmtu_pending = 0;
1237 }
1234 if (!pmtu || (t->pathmtu < pmtu)) 1238 if (!pmtu || (t->pathmtu < pmtu))
1235 pmtu = t->pathmtu; 1239 pmtu = t->pathmtu;
1236 } 1240 }
diff --git a/net/sctp/input.c b/net/sctp/input.c
index 885109fb3dda..d57ff7f3c576 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -367,24 +367,18 @@ static void sctp_add_backlog(struct sock *sk, struct sk_buff *skb)
367void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc, 367void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc,
368 struct sctp_transport *t, __u32 pmtu) 368 struct sctp_transport *t, __u32 pmtu)
369{ 369{
370 if (sock_owned_by_user(sk) || !t || (t->pathmtu == pmtu)) 370 if (!t || (t->pathmtu == pmtu))
371 return; 371 return;
372 372
373 if (sock_owned_by_user(sk)) {
374 asoc->pmtu_pending = 1;
375 t->pmtu_pending = 1;
376 return;
377 }
378
373 if (t->param_flags & SPP_PMTUD_ENABLE) { 379 if (t->param_flags & SPP_PMTUD_ENABLE) {
374 if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) { 380 /* Update transports view of the MTU */
375 printk(KERN_WARNING "%s: Reported pmtu %d too low, " 381 sctp_transport_update_pmtu(t, pmtu);
376 "using default minimum of %d\n",
377 __FUNCTION__, pmtu,
378 SCTP_DEFAULT_MINSEGMENT);
379 /* Use default minimum segment size and disable
380 * pmtu discovery on this transport.
381 */
382 t->pathmtu = SCTP_DEFAULT_MINSEGMENT;
383 t->param_flags = (t->param_flags & ~SPP_PMTUD) |
384 SPP_PMTUD_DISABLE;
385 } else {
386 t->pathmtu = pmtu;
387 }
388 382
389 /* Update association pmtu. */ 383 /* Update association pmtu. */
390 sctp_assoc_sync_pmtu(asoc); 384 sctp_assoc_sync_pmtu(asoc);
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 4dcdabf56473..6edaaa009d62 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -333,12 +333,19 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
333 if (!sp->pf->bind_verify(sp, addr)) 333 if (!sp->pf->bind_verify(sp, addr))
334 return -EADDRNOTAVAIL; 334 return -EADDRNOTAVAIL;
335 335
336 /* We must either be unbound, or bind to the same port. */ 336 /* We must either be unbound, or bind to the same port.
337 if (bp->port && (snum != bp->port)) { 337 * It's OK to allow 0 ports if we are already bound.
338 SCTP_DEBUG_PRINTK("sctp_do_bind:" 338 * We'll just inhert an already bound port in this case
339 */
340 if (bp->port) {
341 if (!snum)
342 snum = bp->port;
343 else if (snum != bp->port) {
344 SCTP_DEBUG_PRINTK("sctp_do_bind:"
339 " New port %d does not match existing port " 345 " New port %d does not match existing port "
340 "%d.\n", snum, bp->port); 346 "%d.\n", snum, bp->port);
341 return -EINVAL; 347 return -EINVAL;
348 }
342 } 349 }
343 350
344 if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE)) 351 if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
@@ -1655,6 +1662,9 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
1655 goto out_free; 1662 goto out_free;
1656 } 1663 }
1657 1664
1665 if (asoc->pmtu_pending)
1666 sctp_assoc_pending_pmtu(asoc);
1667
1658 /* If fragmentation is disabled and the message length exceeds the 1668 /* If fragmentation is disabled and the message length exceeds the
1659 * association fragmentation point, return EMSGSIZE. The I-D 1669 * association fragmentation point, return EMSGSIZE. The I-D
1660 * does not specify what this error is, but this looks like 1670 * does not specify what this error is, but this looks like
@@ -3550,6 +3560,7 @@ SCTP_STATIC int sctp_do_peeloff(struct sctp_association *asoc,
3550 struct sock *sk = asoc->base.sk; 3560 struct sock *sk = asoc->base.sk;
3551 struct socket *sock; 3561 struct socket *sock;
3552 struct inet_sock *inetsk; 3562 struct inet_sock *inetsk;
3563 struct sctp_af *af;
3553 int err = 0; 3564 int err = 0;
3554 3565
3555 /* An association cannot be branched off from an already peeled-off 3566 /* An association cannot be branched off from an already peeled-off
@@ -3571,8 +3582,9 @@ SCTP_STATIC int sctp_do_peeloff(struct sctp_association *asoc,
3571 /* Make peeled-off sockets more like 1-1 accepted sockets. 3582 /* Make peeled-off sockets more like 1-1 accepted sockets.
3572 * Set the daddr and initialize id to something more random 3583 * Set the daddr and initialize id to something more random
3573 */ 3584 */
3585 af = sctp_get_af_specific(asoc->peer.primary_addr.sa.sa_family);
3586 af->to_sk_daddr(&asoc->peer.primary_addr, sk);
3574 inetsk = inet_sk(sock->sk); 3587 inetsk = inet_sk(sock->sk);
3575 inetsk->daddr = asoc->peer.primary_addr.v4.sin_addr.s_addr;
3576 inetsk->id = asoc->next_tsn ^ jiffies; 3588 inetsk->id = asoc->next_tsn ^ jiffies;
3577 3589
3578 *sockp = sock; 3590 *sockp = sock;
@@ -4343,11 +4355,12 @@ copy_getaddrs:
4343 err = -EFAULT; 4355 err = -EFAULT;
4344 goto error; 4356 goto error;
4345 } 4357 }
4346 if (put_user(cnt, &((struct sctp_getaddrs __user *)optval)->addr_num)) 4358 if (put_user(cnt, &((struct sctp_getaddrs __user *)optval)->addr_num)) {
4347 return -EFAULT; 4359 err = -EFAULT;
4360 goto error;
4361 }
4348 if (put_user(bytes_copied, optlen)) 4362 if (put_user(bytes_copied, optlen))
4349 return -EFAULT; 4363 err = -EFAULT;
4350
4351error: 4364error:
4352 kfree(addrs); 4365 kfree(addrs);
4353 return err; 4366 return err;
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index 961df275d5b9..5f467c914f80 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -241,6 +241,45 @@ void sctp_transport_pmtu(struct sctp_transport *transport)
241 transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT; 241 transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT;
242} 242}
243 243
244/* this is a complete rip-off from __sk_dst_check
245 * the cookie is always 0 since this is how it's used in the
246 * pmtu code
247 */
248static struct dst_entry *sctp_transport_dst_check(struct sctp_transport *t)
249{
250 struct dst_entry *dst = t->dst;
251
252 if (dst && dst->obsolete && dst->ops->check(dst, 0) == NULL) {
253 dst_release(t->dst);
254 t->dst = NULL;
255 return NULL;
256 }
257
258 return dst;
259}
260
261void sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu)
262{
263 struct dst_entry *dst;
264
265 if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) {
266 printk(KERN_WARNING "%s: Reported pmtu %d too low, "
267 "using default minimum of %d\n",
268 __FUNCTION__, pmtu,
269 SCTP_DEFAULT_MINSEGMENT);
270 /* Use default minimum segment size and disable
271 * pmtu discovery on this transport.
272 */
273 t->pathmtu = SCTP_DEFAULT_MINSEGMENT;
274 } else {
275 t->pathmtu = pmtu;
276 }
277
278 dst = sctp_transport_dst_check(t);
279 if (dst)
280 dst->ops->update_pmtu(dst, pmtu);
281}
282
244/* Caches the dst entry and source address for a transport's destination 283/* Caches the dst entry and source address for a transport's destination
245 * address. 284 * address.
246 */ 285 */