From d570ee490fb18220262cfe41284d7aede797ed4f Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Tue, 15 May 2007 16:32:39 -0400 Subject: [SCTP]: Correctly set daddr for IPv6 sockets during peeloff During peeloff of AF_INET6 socket, the inet6_sk(sk)->daddr wasn't set correctly since the code was assuming IPv4 only. Now we use a correct call to set the destination address. Signed-off-by: Vlad Yasevich Acked-by: Sridhar Samudrala --- net/sctp/socket.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'net/sctp/socket.c') diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 4dcdabf56473..d370c945a757 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -3550,6 +3550,7 @@ SCTP_STATIC int sctp_do_peeloff(struct sctp_association *asoc, struct sock *sk = asoc->base.sk; struct socket *sock; struct inet_sock *inetsk; + struct sctp_af *af; int err = 0; /* An association cannot be branched off from an already peeled-off @@ -3571,8 +3572,9 @@ SCTP_STATIC int sctp_do_peeloff(struct sctp_association *asoc, /* Make peeled-off sockets more like 1-1 accepted sockets. * Set the daddr and initialize id to something more random */ + af = sctp_get_af_specific(asoc->peer.primary_addr.sa.sa_family); + af->to_sk_daddr(&asoc->peer.primary_addr, sk); inetsk = inet_sk(sock->sk); - inetsk->daddr = asoc->peer.primary_addr.v4.sin_addr.s_addr; inetsk->id = asoc->next_tsn ^ jiffies; *sockp = sock; -- cgit v1.2.2 From 8b35805693e1915829355723537f99f1b8bc9cc0 Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Tue, 15 May 2007 17:14:58 -0400 Subject: [SCTP]: Allow unspecified port in sctp_bindx() Allow sctp_bindx() to accept multiple address with unspecified port. In this case, all addresses inherit the first bound port. We still catch full mis-matches. Signed-off-by: Vlad Yasevich Acked-by: Sridhar Samudrala --- net/sctp/socket.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'net/sctp/socket.c') diff --git a/net/sctp/socket.c b/net/sctp/socket.c index d370c945a757..a5b6e559451e 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) if (!sp->pf->bind_verify(sp, addr)) return -EADDRNOTAVAIL; - /* We must either be unbound, or bind to the same port. */ - if (bp->port && (snum != bp->port)) { - SCTP_DEBUG_PRINTK("sctp_do_bind:" + /* We must either be unbound, or bind to the same port. + * It's OK to allow 0 ports if we are already bound. + * We'll just inhert an already bound port in this case + */ + if (bp->port) { + if (!snum) + snum = bp->port; + else if (snum != bp->port) { + SCTP_DEBUG_PRINTK("sctp_do_bind:" " New port %d does not match existing port " "%d.\n", snum, bp->port); - return -EINVAL; + return -EINVAL; + } } if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE)) -- cgit v1.2.2 From fe979ac169970b3d12facd6565766735862395c5 Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Wed, 23 May 2007 11:11:37 -0400 Subject: [SCTP] Fix leak in sctp_getsockopt_local_addrs when copy_to_user fails If the copy_to_user or copy_user calls fail in sctp_getsockopt_local_addrs(), the function should free locally allocated storage before returning error. Spotted by Coverity. Signed-off-by: Vlad Yasevich Acked-by: Sridhar Samudrala --- net/sctp/socket.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'net/sctp/socket.c') diff --git a/net/sctp/socket.c b/net/sctp/socket.c index a5b6e559451e..45510c46c223 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -4352,11 +4352,12 @@ copy_getaddrs: err = -EFAULT; goto error; } - if (put_user(cnt, &((struct sctp_getaddrs __user *)optval)->addr_num)) - return -EFAULT; + if (put_user(cnt, &((struct sctp_getaddrs __user *)optval)->addr_num)) { + err = -EFAULT; + goto error; + } if (put_user(bytes_copied, optlen)) - return -EFAULT; - + err = -EFAULT; error: kfree(addrs); return err; -- cgit v1.2.2 From 8a4794914f9cf2681235ec2311e189fe307c28c7 Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Thu, 7 Jun 2007 14:21:05 -0400 Subject: [SCTP] Flag a pmtu change request Currently, if the socket is owned by the user, we drop the ICMP message. As a result SCTP forgets that path MTU changed and never adjusting it's estimate. This causes all subsequent packets to be fragmented. With this patch, we'll flag the association that it needs to udpate it's estimate based on the already updated routing information. Signed-off-by: Vlad Yasevich Acked-by: Sridhar Samudrala --- net/sctp/socket.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'net/sctp/socket.c') diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 45510c46c223..6edaaa009d62 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -1662,6 +1662,9 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, goto out_free; } + if (asoc->pmtu_pending) + sctp_assoc_pending_pmtu(asoc); + /* If fragmentation is disabled and the message length exceeds the * association fragmentation point, return EMSGSIZE. The I-D * does not specify what this error is, but this looks like -- cgit v1.2.2