netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATC] sctp: various fixes
@ 2008-07-19  4:26 Vlad Yasevich
  2008-07-19  4:26 ` [PATCH 1/7] sctp: Don't abort initialization when CONFIG_PROC_FS=n Vlad Yasevich
                   ` (7 more replies)
  0 siblings, 8 replies; 13+ messages in thread
From: Vlad Yasevich @ 2008-07-19  4:26 UTC (permalink / raw)
  To: netdev; +Cc: davem, linux-sctp

Hi David

This is a bunch of SCTP fixes that have accumlated over the past week or
so. 

Here is the shortlog:

Florian Westphal (2):
      sctp: Don't abort initialization when CONFIG_PROC_FS=n
      sctp: Prevent uninitialized memory access

Harvey Harrison (1):
      sctp: remove unnecessary byteshifting, calculate directly in big-endian

Vlad Yasevich (4):
      sctp: Support ipv6only AF_INET6 sockets.
      sctp: Do not leak memory on multiple listen() calls
      sctp: Allow only 1 listening socket with SO_REUSEADDR
      sctp: Update sctp global memory limit allocations.

Please apply.  Thanks
-vlad

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 1/7] sctp: Don't abort initialization when CONFIG_PROC_FS=n
  2008-07-19  4:26 [PATC] sctp: various fixes Vlad Yasevich
@ 2008-07-19  4:26 ` Vlad Yasevich
  2008-07-19  4:26 ` [PATCH 2/7] sctp: Prevent uninitialized memory access Vlad Yasevich
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Vlad Yasevich @ 2008-07-19  4:26 UTC (permalink / raw)
  To: netdev; +Cc: davem, linux-sctp, Florian Westphal, Vlad Yasevich

From: Florian Westphal <fw@strlen.de>

This puts CONFIG_PROC_FS defines around the proc init/exit functions
and also avoids compiling proc.c if procfs is not supported.
Also make SCTP_DBG_OBJCNT depend on procfs.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
---
 net/sctp/Kconfig    |    4 ++--
 net/sctp/Makefile   |    4 ++--
 net/sctp/protocol.c |   11 ++++++++++-
 3 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/net/sctp/Kconfig b/net/sctp/Kconfig
index 0b79f86..58b3e88 100644
--- a/net/sctp/Kconfig
+++ b/net/sctp/Kconfig
@@ -47,11 +47,11 @@ config SCTP_DBG_MSG
 
 config SCTP_DBG_OBJCNT
 	bool "SCTP: Debug object counts"
+	depends on PROC_FS
 	help
 	  If you say Y, this will enable debugging support for counting the 
 	  type of objects that are currently allocated.  This is useful for 
-	  identifying memory leaks.   If the /proc filesystem is enabled this 
-	  debug information can be viewed by 
+	  identifying memory leaks. This debug information can be viewed by
 	  'cat /proc/net/sctp/sctp_dbg_objcnt'
 
 	  If unsure, say N
diff --git a/net/sctp/Makefile b/net/sctp/Makefile
index f5356b9..6b79473 100644
--- a/net/sctp/Makefile
+++ b/net/sctp/Makefile
@@ -9,10 +9,10 @@ sctp-y := sm_statetable.o sm_statefuns.o sm_sideeffect.o \
 	  transport.o chunk.o sm_make_chunk.o ulpevent.o \
 	  inqueue.o outqueue.o ulpqueue.o command.o \
 	  tsnmap.o bind_addr.o socket.o primitive.o \
-	  output.o input.o debug.o ssnmap.o proc.o \
-	  auth.o
+	  output.o input.o debug.o ssnmap.o auth.o
 
 sctp-$(CONFIG_SCTP_DBG_OBJCNT) += objcnt.o
+sctp-$(CONFIG_PROC_FS) += proc.o
 sctp-$(CONFIG_SYSCTL) += sysctl.o
 
 sctp-$(subst m,y,$(CONFIG_IPV6))	+= ipv6.o
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 98c6a88..dd811a8 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -64,9 +64,12 @@
 
 /* Global data structures. */
 struct sctp_globals sctp_globals __read_mostly;
-struct proc_dir_entry	*proc_net_sctp;
 DEFINE_SNMP_STAT(struct sctp_mib, sctp_statistics) __read_mostly;
 
+#ifdef CONFIG_PROC_FS
+struct proc_dir_entry	*proc_net_sctp;
+#endif
+
 struct idr sctp_assocs_id;
 DEFINE_SPINLOCK(sctp_assocs_id_lock);
 
@@ -97,6 +100,7 @@ struct sock *sctp_get_ctl_sock(void)
 /* Set up the proc fs entry for the SCTP protocol. */
 static __init int sctp_proc_init(void)
 {
+#ifdef CONFIG_PROC_FS
 	if (!proc_net_sctp) {
 		struct proc_dir_entry *ent;
 		ent = proc_mkdir("sctp", init_net.proc_net);
@@ -131,6 +135,9 @@ out_snmp_proc_init:
 	}
 out_nomem:
 	return -ENOMEM;
+#else
+	return 0;
+#endif /* CONFIG_PROC_FS */
 }
 
 /* Clean up the proc fs entry for the SCTP protocol.
@@ -139,6 +146,7 @@ out_nomem:
  */
 static void sctp_proc_exit(void)
 {
+#ifdef CONFIG_PROC_FS
 	sctp_snmp_proc_exit();
 	sctp_eps_proc_exit();
 	sctp_assocs_proc_exit();
@@ -148,6 +156,7 @@ static void sctp_proc_exit(void)
 		proc_net_sctp = NULL;
 		remove_proc_entry("sctp", init_net.proc_net);
 	}
+#endif
 }
 
 /* Private helper to extract ipv4 address and stash them in
-- 
1.5.2.5


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 2/7] sctp: Prevent uninitialized memory access
  2008-07-19  4:26 [PATC] sctp: various fixes Vlad Yasevich
  2008-07-19  4:26 ` [PATCH 1/7] sctp: Don't abort initialization when CONFIG_PROC_FS=n Vlad Yasevich
@ 2008-07-19  4:26 ` Vlad Yasevich
  2008-07-19  4:26 ` [PATCH 3/7] sctp: Support ipv6only AF_INET6 sockets Vlad Yasevich
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Vlad Yasevich @ 2008-07-19  4:26 UTC (permalink / raw)
  To: netdev; +Cc: davem, linux-sctp, Florian Westphal, Vlad Yasevich

From: Florian Westphal <fw@strlen.de>

valgrind reports uninizialized memory accesses when running
sctp inside the network simulation cradle simulator:

 Conditional jump or move depends on uninitialised value(s)
    at 0x570E34A: sctp_assoc_sync_pmtu (associola.c:1324)
    by 0x57427DA: sctp_packet_transmit (output.c:403)
    by 0x5710EFF: sctp_outq_flush (outqueue.c:824)
    by 0x5710B88: sctp_outq_uncork (outqueue.c:701)
    by 0x5745262: sctp_cmd_interpreter (sm_sideeffect.c:1548)
    by 0x57444B7: sctp_side_effects (sm_sideeffect.c:976)
    by 0x5744460: sctp_do_sm (sm_sideeffect.c:945)
    by 0x572157D: sctp_primitive_ASSOCIATE (primitive.c:94)
    by 0x5725C04: __sctp_connect (socket.c:1094)
    by 0x57297DC: sctp_connect (socket.c:3297)

 Conditional jump or move depends on uninitialised value(s)
    at 0x575D3A5: mod_timer (timer.c:630)
    by 0x5752B78: sctp_cmd_hb_timers_start (sm_sideeffect.c:555)
    by 0x5754133: sctp_cmd_interpreter (sm_sideeffect.c:1448)
    by 0x5753607: sctp_side_effects (sm_sideeffect.c:976)
    by 0x57535B0: sctp_do_sm (sm_sideeffect.c:945)
    by 0x571E9AE: sctp_endpoint_bh_rcv (endpointola.c:474)
    by 0x573347F: sctp_inq_push (inqueue.c:104)
    by 0x572EF93: sctp_rcv (input.c:256)
    by 0x5689623: ip_local_deliver_finish (ip_input.c:230)
    by 0x5689759: ip_local_deliver (ip_input.c:268)
    by 0x5689CAC: ip_rcv_finish (dst.h:246)

#1 is due to "if (t->pmtu_pending)".
8a4794914f9cf2681235ec2311e189fe307c28c7 "[SCTP] Flag a pmtu change request"
suggests it should be initialized to 0.

#2 is the heartbeat timer 'expires' value, which is uninizialised, but
test by mod_timer().
T3_rtx_timer seems to be affected by the same problem, so initialize it, too.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
---
 net/sctp/associola.c |    1 +
 net/sctp/transport.c |    3 +++
 2 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 35b6a02..ec2a0a3 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -653,6 +653,7 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
 
 	SCTP_DEBUG_PRINTK("sctp_assoc_add_peer:association %p PMTU set to "
 			  "%d\n", asoc, asoc->pathmtu);
+	peer->pmtu_pending = 0;
 
 	asoc->frag_point = sctp_frag_point(sp, asoc->pathmtu);
 
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index 3f34f61..e745c11 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -100,6 +100,9 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
 	INIT_LIST_HEAD(&peer->send_ready);
 	INIT_LIST_HEAD(&peer->transports);
 
+	peer->T3_rtx_timer.expires = 0;
+	peer->hb_timer.expires = 0;
+
 	setup_timer(&peer->T3_rtx_timer, sctp_generate_t3_rtx_event,
 			(unsigned long)peer);
 	setup_timer(&peer->hb_timer, sctp_generate_heartbeat_event,
-- 
1.5.2.5


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 3/7] sctp: Support ipv6only AF_INET6 sockets.
  2008-07-19  4:26 [PATC] sctp: various fixes Vlad Yasevich
  2008-07-19  4:26 ` [PATCH 1/7] sctp: Don't abort initialization when CONFIG_PROC_FS=n Vlad Yasevich
  2008-07-19  4:26 ` [PATCH 2/7] sctp: Prevent uninitialized memory access Vlad Yasevich
@ 2008-07-19  4:26 ` Vlad Yasevich
  2008-07-19  4:26 ` [PATCH 4/7] sctp: Do not leak memory on multiple listen() calls Vlad Yasevich
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Vlad Yasevich @ 2008-07-19  4:26 UTC (permalink / raw)
  To: netdev; +Cc: davem, linux-sctp, Vlad Yasevich

Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
---
 include/net/sctp/structs.h |    2 ++
 net/sctp/bind_addr.c       |   37 +++++++++++++++++++++++++++++++++++++
 net/sctp/ipv6.c            |   20 ++++++++++++++++----
 net/sctp/protocol.c        |    7 +++++++
 net/sctp/sm_make_chunk.c   |    7 ++++++-
 net/sctp/socket.c          |   30 +++++++++++++++++++++++++-----
 6 files changed, 93 insertions(+), 10 deletions(-)

diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 82116e8..70eb64a 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -1211,6 +1211,8 @@ int sctp_add_bind_addr(struct sctp_bind_addr *, union sctp_addr *,
 int sctp_del_bind_addr(struct sctp_bind_addr *, union sctp_addr *);
 int sctp_bind_addr_match(struct sctp_bind_addr *, const union sctp_addr *,
 			 struct sctp_sock *);
+int sctp_bind_addr_conflict(struct sctp_bind_addr *, const union sctp_addr *,
+			 struct sctp_sock *, struct sctp_sock *);
 int sctp_bind_addr_state(const struct sctp_bind_addr *bp,
 			 const union sctp_addr *addr);
 union sctp_addr *sctp_find_unmatch_addr(struct sctp_bind_addr	*bp,
diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c
index 80e6df0..f62bc24 100644
--- a/net/sctp/bind_addr.c
+++ b/net/sctp/bind_addr.c
@@ -348,6 +348,43 @@ int sctp_bind_addr_match(struct sctp_bind_addr *bp,
 	return match;
 }
 
+/* Does the address 'addr' conflict with any addresses in
+ * the bp.
+ */
+int sctp_bind_addr_conflict(struct sctp_bind_addr *bp,
+			    const union sctp_addr *addr,
+			    struct sctp_sock *bp_sp,
+			    struct sctp_sock *addr_sp)
+{
+	struct sctp_sockaddr_entry *laddr;
+	int conflict = 0;
+	struct sctp_sock *sp;
+
+	/* Pick the IPv6 socket as the basis of comparison
+	 * since it's usually a superset of the IPv4.
+	 * If there is no IPv6 socket, then default to bind_addr.
+	 */
+	if (sctp_opt2sk(bp_sp)->sk_family == AF_INET6)
+		sp = bp_sp;
+	else if (sctp_opt2sk(addr_sp)->sk_family == AF_INET6)
+		sp = addr_sp;
+	else
+		sp = bp_sp;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(laddr, &bp->address_list, list) {
+		if (!laddr->valid)
+			continue;
+
+		conflict = sp->pf->cmp_addr(&laddr->a, addr, sp);
+		if (conflict)
+			break;
+	}
+	rcu_read_unlock();
+
+	return conflict;
+}
+
 /* Get the state of the entry in the bind_addr_list */
 int sctp_bind_addr_state(const struct sctp_bind_addr *bp,
 			 const union sctp_addr *addr)
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index a2f4d4d..a238d68 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -818,7 +818,7 @@ static int sctp_inet6_af_supported(sa_family_t family, struct sctp_sock *sp)
 		return 1;
 	/* v4-mapped-v6 addresses */
 	case AF_INET:
-		if (!__ipv6_only_sock(sctp_opt2sk(sp)) && sp->v4mapped)
+		if (!__ipv6_only_sock(sctp_opt2sk(sp)))
 			return 1;
 	default:
 		return 0;
@@ -840,6 +840,11 @@ static int sctp_inet6_cmp_addr(const union sctp_addr *addr1,
 
 	if (!af1 || !af2)
 		return 0;
+
+	/* If the socket is IPv6 only, v4 addrs will not match */
+	if (__ipv6_only_sock(sctp_opt2sk(opt)) && af1 != af2)
+		return 0;
+
 	/* Today, wildcard AF_INET/AF_INET6. */
 	if (sctp_is_any(addr1) || sctp_is_any(addr2))
 		return 1;
@@ -876,7 +881,11 @@ static int sctp_inet6_bind_verify(struct sctp_sock *opt, union sctp_addr *addr)
 				return 0;
 			}
 			dev_put(dev);
+		} else if (type == IPV6_ADDR_MAPPED) {
+			if (!opt->v4mapped)
+				return 0;
 		}
+
 		af = opt->pf->af;
 	}
 	return af->available(addr, opt);
@@ -919,9 +928,12 @@ static int sctp_inet6_send_verify(struct sctp_sock *opt, union sctp_addr *addr)
 static int sctp_inet6_supported_addrs(const struct sctp_sock *opt,
 				      __be16 *types)
 {
-	types[0] = SCTP_PARAM_IPV4_ADDRESS;
-	types[1] = SCTP_PARAM_IPV6_ADDRESS;
-	return 2;
+	types[0] = SCTP_PARAM_IPV6_ADDRESS;
+	if (!opt || !ipv6_only_sock(sctp_opt2sk(opt))) {
+		types[1] = SCTP_PARAM_IPV4_ADDRESS;
+		return 2;
+	}
+	return 1;
 }
 
 static const struct proto_ops inet6_seqpacket_ops = {
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index dd811a8..cdd8811 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -381,6 +381,10 @@ static int sctp_v4_addr_valid(union sctp_addr *addr,
 			      struct sctp_sock *sp,
 			      const struct sk_buff *skb)
 {
+	/* IPv4 addresses not allowed */
+	if (sp && ipv6_only_sock(sctp_opt2sk(sp)))
+		return 0;
+
 	/* Is this a non-unicast address or a unusable SCTP address? */
 	if (IS_IPV4_UNUSABLE_ADDRESS(addr->v4.sin_addr.s_addr))
 		return 0;
@@ -404,6 +408,9 @@ static int sctp_v4_available(union sctp_addr *addr, struct sctp_sock *sp)
 	   !sysctl_ip_nonlocal_bind)
 		return 0;
 
+	if (ipv6_only_sock(sctp_opt2sk(sp)))
+		return 0;
+
 	return 1;
 }
 
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index bbc7107..e8ca4e5 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -2364,8 +2364,13 @@ static int sctp_process_param(struct sctp_association *asoc,
 	case SCTP_PARAM_IPV6_ADDRESS:
 		if (PF_INET6 != asoc->base.sk->sk_family)
 			break;
-		/* Fall through. */
+		goto do_addr_param;
+
 	case SCTP_PARAM_IPV4_ADDRESS:
+		/* v4 addresses are not allowed on v6-only socket */
+		if (ipv6_only_sock(asoc->base.sk))
+			break;
+do_addr_param:
 		af = sctp_get_af_specific(param_type2af(param.p->type));
 		af->from_addr_param(&addr, param.addr, htons(asoc->peer.port), 0);
 		scope = sctp_scope(peer_addr);
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 6aba01b..a0e879b 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -308,9 +308,16 @@ static struct sctp_af *sctp_sockaddr_af(struct sctp_sock *opt,
 	if (len < sizeof (struct sockaddr))
 		return NULL;
 
-	/* Does this PF support this AF? */
-	if (!opt->pf->af_supported(addr->sa.sa_family, opt))
-		return NULL;
+	/* V4 mapped address are really of AF_INET family */
+	if (addr->sa.sa_family == AF_INET6 &&
+	    ipv6_addr_v4mapped(&addr->v6.sin6_addr)) {
+		if (!opt->pf->af_supported(AF_INET, opt))
+			return NULL;
+	} else {
+		/* Does this PF support this AF? */
+		if (!opt->pf->af_supported(addr->sa.sa_family, opt))
+			return NULL;
+	}
 
 	/* If we get this far, af is valid. */
 	af = sctp_get_af_specific(addr->sa.sa_family);
@@ -4395,6 +4402,11 @@ static int sctp_getsockopt_local_addrs_num_old(struct sock *sk, int len,
 				    (AF_INET6 == addr->a.sa.sa_family))
 					continue;
 
+				if ((PF_INET6 == sk->sk_family) &&
+				    inet_v6_ipv6only(sk) &&
+				    (AF_INET == addr->a.sa.sa_family))
+					continue;
+
 				cnt++;
 			}
 			rcu_read_unlock();
@@ -4435,6 +4447,10 @@ static int sctp_copy_laddrs_old(struct sock *sk, __u16 port,
 		if ((PF_INET == sk->sk_family) &&
 		    (AF_INET6 == addr->a.sa.sa_family))
 			continue;
+		if ((PF_INET6 == sk->sk_family) &&
+		    inet_v6_ipv6only(sk) &&
+		    (AF_INET == addr->a.sa.sa_family))
+			continue;
 		memcpy(&temp, &addr->a, sizeof(temp));
 		if (!temp.v4.sin_port)
 			temp.v4.sin_port = htons(port);
@@ -4470,6 +4486,10 @@ static int sctp_copy_laddrs(struct sock *sk, __u16 port, void *to,
 		if ((PF_INET == sk->sk_family) &&
 		    (AF_INET6 == addr->a.sa.sa_family))
 			continue;
+		if ((PF_INET6 == sk->sk_family) &&
+		    inet_v6_ipv6only(sk) &&
+		    (AF_INET == addr->a.sa.sa_family))
+			continue;
 		memcpy(&temp, &addr->a, sizeof(temp));
 		if (!temp.v4.sin_port)
 			temp.v4.sin_port = htons(port);
@@ -5568,8 +5588,8 @@ pp_found:
 			    sk2->sk_state != SCTP_SS_LISTENING)
 				continue;
 
-			if (sctp_bind_addr_match(&ep2->base.bind_addr, addr,
-						 sctp_sk(sk))) {
+			if (sctp_bind_addr_conflict(&ep2->base.bind_addr, addr,
+						 sctp_sk(sk2), sctp_sk(sk))) {
 				ret = (long)sk2;
 				goto fail_unlock;
 			}
-- 
1.5.2.5


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 4/7] sctp: Do not leak memory on multiple listen() calls
  2008-07-19  4:26 [PATC] sctp: various fixes Vlad Yasevich
                   ` (2 preceding siblings ...)
  2008-07-19  4:26 ` [PATCH 3/7] sctp: Support ipv6only AF_INET6 sockets Vlad Yasevich
@ 2008-07-19  4:26 ` Vlad Yasevich
  2008-07-19  4:26 ` [PATCH 5/7] sctp: Allow only 1 listening socket with SO_REUSEADDR Vlad Yasevich
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Vlad Yasevich @ 2008-07-19  4:26 UTC (permalink / raw)
  To: netdev; +Cc: davem, linux-sctp, Vlad Yasevich

SCTP permits multiple listen call and on subsequent calls
we leak he memory allocated for the crypto transforms.

Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
---
 net/sctp/socket.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index a0e879b..fd7ed9d 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -5773,7 +5773,7 @@ int sctp_inet_listen(struct socket *sock, int backlog)
 		goto out;
 
 	/* Allocate HMAC for generating cookie. */
-	if (sctp_hmac_alg) {
+	if (!sctp_sk(sk)->hmac && sctp_hmac_alg) {
 		tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC);
 		if (IS_ERR(tfm)) {
 			if (net_ratelimit()) {
@@ -5801,7 +5801,8 @@ int sctp_inet_listen(struct socket *sock, int backlog)
 		goto cleanup;
 
 	/* Store away the transform reference. */
-	sctp_sk(sk)->hmac = tfm;
+	if (!sctp_sk(sk)->hmac)
+		sctp_sk(sk)->hmac = tfm;
 out:
 	sctp_release_sock(sk);
 	return err;
-- 
1.5.2.5


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 5/7] sctp: Allow only 1 listening socket with SO_REUSEADDR
  2008-07-19  4:26 [PATC] sctp: various fixes Vlad Yasevich
                   ` (3 preceding siblings ...)
  2008-07-19  4:26 ` [PATCH 4/7] sctp: Do not leak memory on multiple listen() calls Vlad Yasevich
@ 2008-07-19  4:26 ` Vlad Yasevich
  2008-07-19  4:26 ` [PATCH 6/7] sctp: remove unnecessary byteshifting, calculate directly in big-endian Vlad Yasevich
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Vlad Yasevich @ 2008-07-19  4:26 UTC (permalink / raw)
  To: netdev; +Cc: davem, linux-sctp, Vlad Yasevich

When multiple socket bind to the same port with SO_REUSEADDR,
only 1 can be listining.

Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
---
 net/sctp/socket.c |   25 ++++++++++++++++---------
 1 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index fd7ed9d..79bece1 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -377,18 +377,19 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
 	if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
 		return -EACCES;
 
+	/* See if the address matches any of the addresses we may have
+	 * already bound before checking against other endpoints.
+	 */
+	if (sctp_bind_addr_match(bp, addr, sp))
+		return -EINVAL;
+
 	/* Make sure we are allowed to bind here.
 	 * The function sctp_get_port_local() does duplicate address
 	 * detection.
 	 */
 	addr->v4.sin_port = htons(snum);
 	if ((ret = sctp_get_port_local(sk, addr))) {
-		if (ret == (long) sk) {
-			/* This endpoint has a conflicting address. */
-			return -EINVAL;
-		} else {
-			return -EADDRINUSE;
-		}
+		return -EADDRINUSE;
 	}
 
 	/* Refresh ephemeral port.  */
@@ -5584,8 +5585,9 @@ pp_found:
 			struct sctp_endpoint *ep2;
 			ep2 = sctp_sk(sk2)->ep;
 
-			if (reuse && sk2->sk_reuse &&
-			    sk2->sk_state != SCTP_SS_LISTENING)
+			if (sk == sk2 ||
+			    (reuse && sk2->sk_reuse &&
+			     sk2->sk_state != SCTP_SS_LISTENING))
 				continue;
 
 			if (sctp_bind_addr_conflict(&ep2->base.bind_addr, addr,
@@ -5702,8 +5704,13 @@ SCTP_STATIC int sctp_seqpacket_listen(struct sock *sk, int backlog)
 	if (!ep->base.bind_addr.port) {
 		if (sctp_autobind(sk))
 			return -EAGAIN;
-	} else
+	} else {
+		if (sctp_get_port(sk, inet_sk(sk)->num)) {
+			sk->sk_state = SCTP_SS_CLOSED;
+			return -EADDRINUSE;
+		}
 		sctp_sk(sk)->bind_hash->fastreuse = 0;
+	}
 
 	sctp_hash_endpoint(ep);
 	return 0;
-- 
1.5.2.5


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 6/7] sctp: remove unnecessary byteshifting, calculate directly in big-endian
  2008-07-19  4:26 [PATC] sctp: various fixes Vlad Yasevich
                   ` (4 preceding siblings ...)
  2008-07-19  4:26 ` [PATCH 5/7] sctp: Allow only 1 listening socket with SO_REUSEADDR Vlad Yasevich
@ 2008-07-19  4:26 ` Vlad Yasevich
  2008-07-19  4:26 ` [PATCH 7/7] sctp: Update sctp global memory limit allocations Vlad Yasevich
  2008-07-19  6:08 ` [PATC] sctp: various fixes David Miller
  7 siblings, 0 replies; 13+ messages in thread
From: Vlad Yasevich @ 2008-07-19  4:26 UTC (permalink / raw)
  To: netdev; +Cc: davem, linux-sctp, Harvey Harrison, Vlad Yasevich

From: Harvey Harrison <harvey.harrison@gmail.com>

Signed-off-by: Harvey Harrison <harvey.harrison@gmail.com>
Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
---
 include/net/sctp/checksum.h            |   23 ++++++++++++++---------
 net/ipv4/netfilter/nf_nat_proto_sctp.c |    4 ++--
 net/sctp/input.c                       |    4 ++--
 net/sctp/output.c                      |    4 ++--
 4 files changed, 20 insertions(+), 15 deletions(-)

diff --git a/include/net/sctp/checksum.h b/include/net/sctp/checksum.h
index ba75c67..b799fb2 100644
--- a/include/net/sctp/checksum.h
+++ b/include/net/sctp/checksum.h
@@ -46,9 +46,14 @@
 #include <net/sctp/sctp.h>
 #include <linux/crc32c.h>
 
-static inline __u32 sctp_start_cksum(__u8 *buffer, __u16 length)
+static inline __be32 sctp_crc32c(__be32 crc, u8 *buffer, u16 length)
 {
-	__u32 crc = ~(__u32) 0;
+	return (__force __be32)crc32c((__force u32)crc, buffer, length);
+}
+
+static inline __be32 sctp_start_cksum(__u8 *buffer, __u16 length)
+{
+	__be32 crc = ~cpu_to_be32(0);
 	__u8  zero[sizeof(__u32)] = {0};
 
 	/* Optimize this routine to be SCTP specific, knowing how
@@ -56,23 +61,23 @@ static inline __u32 sctp_start_cksum(__u8 *buffer, __u16 length)
 	 */
 
 	/* Calculate CRC up to the checksum. */
-	crc = crc32c(crc, buffer, sizeof(struct sctphdr) - sizeof(__u32));
+	crc = sctp_crc32c(crc, buffer, sizeof(struct sctphdr) - sizeof(__u32));
 
 	/* Skip checksum field of the header. */
-	crc = crc32c(crc, zero, sizeof(__u32));
+	crc = sctp_crc32c(crc, zero, sizeof(__u32));
 
 	/* Calculate the rest of the CRC. */
-	crc = crc32c(crc, &buffer[sizeof(struct sctphdr)],
+	crc = sctp_crc32c(crc, &buffer[sizeof(struct sctphdr)],
 			    length - sizeof(struct sctphdr));
 	return crc;
 }
 
-static inline __u32 sctp_update_cksum(__u8 *buffer, __u16 length, __u32 crc32)
+static inline __be32 sctp_update_cksum(__u8 *buffer, __u16 length, __be32 crc32)
 {
-	return crc32c(crc32, buffer, length);
+	return sctp_crc32c(crc32, buffer, length);
 }
 
-static inline __u32 sctp_end_cksum(__u32 crc32)
+static inline __be32 sctp_end_cksum(__be32 crc32)
 {
-	return ntohl(~crc32);
+	return ~crc32;
 }
diff --git a/net/ipv4/netfilter/nf_nat_proto_sctp.c b/net/ipv4/netfilter/nf_nat_proto_sctp.c
index 82e4c0e..65e470b 100644
--- a/net/ipv4/netfilter/nf_nat_proto_sctp.c
+++ b/net/ipv4/netfilter/nf_nat_proto_sctp.c
@@ -36,7 +36,7 @@ sctp_manip_pkt(struct sk_buff *skb,
 	sctp_sctphdr_t *hdr;
 	unsigned int hdroff = iphdroff + iph->ihl*4;
 	__be32 oldip, newip;
-	u32 crc32;
+	__be32 crc32;
 
 	if (!skb_make_writable(skb, hdroff + sizeof(*hdr)))
 		return false;
@@ -61,7 +61,7 @@ sctp_manip_pkt(struct sk_buff *skb,
 		crc32 = sctp_update_cksum((u8 *)skb->data, skb_headlen(skb),
 					  crc32);
 	crc32 = sctp_end_cksum(crc32);
-	hdr->checksum = htonl(crc32);
+	hdr->checksum = crc32;
 
 	return true;
 }
diff --git a/net/sctp/input.c b/net/sctp/input.c
index 5ed93c0..a49fa80 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -83,8 +83,8 @@ static inline int sctp_rcv_checksum(struct sk_buff *skb)
 {
 	struct sk_buff *list = skb_shinfo(skb)->frag_list;
 	struct sctphdr *sh = sctp_hdr(skb);
-	__u32 cmp = ntohl(sh->checksum);
-	__u32 val = sctp_start_cksum((__u8 *)sh, skb_headlen(skb));
+	__be32 cmp = sh->checksum;
+	__be32 val = sctp_start_cksum((__u8 *)sh, skb_headlen(skb));
 
 	for (; list; list = list->next)
 		val = sctp_update_cksum((__u8 *)list->data, skb_headlen(list),
diff --git a/net/sctp/output.c b/net/sctp/output.c
index 9a63a3f..4568464 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -365,7 +365,7 @@ int sctp_packet_transmit(struct sctp_packet *packet)
 	struct sctp_transport *tp = packet->transport;
 	struct sctp_association *asoc = tp->asoc;
 	struct sctphdr *sh;
-	__u32 crc32 = 0;
+	__be32 crc32 = __constant_cpu_to_be32(0);
 	struct sk_buff *nskb;
 	struct sctp_chunk *chunk, *tmp;
 	struct sock *sk;
@@ -538,7 +538,7 @@ int sctp_packet_transmit(struct sctp_packet *packet)
 	/* 3) Put the resultant value into the checksum field in the
 	 *    common header, and leave the rest of the bits unchanged.
 	 */
-	sh->checksum = htonl(crc32);
+	sh->checksum = crc32;
 
 	/* IP layer ECN support
 	 * From RFC 2481
-- 
1.5.2.5


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 7/7] sctp: Update sctp global memory limit allocations.
  2008-07-19  4:26 [PATC] sctp: various fixes Vlad Yasevich
                   ` (5 preceding siblings ...)
  2008-07-19  4:26 ` [PATCH 6/7] sctp: remove unnecessary byteshifting, calculate directly in big-endian Vlad Yasevich
@ 2008-07-19  4:26 ` Vlad Yasevich
  2008-07-19  6:08 ` [PATC] sctp: various fixes David Miller
  7 siblings, 0 replies; 13+ messages in thread
From: Vlad Yasevich @ 2008-07-19  4:26 UTC (permalink / raw)
  To: netdev; +Cc: davem, linux-sctp, Vlad Yasevich

Update sctp global memory limit allocations to be the same as
TCP.

Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
---
 net/sctp/protocol.c |   10 +++++++---
 1 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index cdd8811..ed9acff 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -52,6 +52,8 @@
 #include <linux/inetdevice.h>
 #include <linux/seq_file.h>
 #include <linux/bootmem.h>
+#include <linux/highmem.h>
+#include <linux/swap.h>
 #include <net/net_namespace.h>
 #include <net/protocol.h>
 #include <net/ip.h>
@@ -1080,6 +1082,7 @@ SCTP_STATIC __init int sctp_init(void)
 	int status = -EINVAL;
 	unsigned long goal;
 	unsigned long limit;
+	unsigned long nr_pages;
 	int max_share;
 	int order;
 
@@ -1175,8 +1178,9 @@ SCTP_STATIC __init int sctp_init(void)
 	 * Note this initalizes the data in sctpv6_prot too
 	 * Unabashedly stolen from tcp_init
 	 */
-	limit = min(num_physpages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT);
-	limit = (limit * (num_physpages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11);
+	nr_pages = totalram_pages - totalhigh_pages;
+	limit = min(nr_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT);
+	limit = (limit * (nr_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11);
 	limit = max(limit, 128UL);
 	sysctl_sctp_mem[0] = limit / 4 * 3;
 	sysctl_sctp_mem[1] = limit;
@@ -1186,7 +1190,7 @@ SCTP_STATIC __init int sctp_init(void)
 	limit = (sysctl_sctp_mem[1]) << (PAGE_SHIFT - 7);
 	max_share = min(4UL*1024*1024, limit);
 
-	sysctl_sctp_rmem[0] = PAGE_SIZE; /* give each asoc 1 page min */
+	sysctl_sctp_rmem[0] = SK_MEM_QUANTUM; /* give each asoc 1 page min */
 	sysctl_sctp_rmem[1] = (1500 *(sizeof(struct sk_buff) + 1));
 	sysctl_sctp_rmem[2] = max(sysctl_sctp_rmem[1], max_share);
 
-- 
1.5.2.5


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATC] sctp: various fixes
  2008-07-19  4:26 [PATC] sctp: various fixes Vlad Yasevich
                   ` (6 preceding siblings ...)
  2008-07-19  4:26 ` [PATCH 7/7] sctp: Update sctp global memory limit allocations Vlad Yasevich
@ 2008-07-19  6:08 ` David Miller
  2008-07-20  5:40   ` David Miller
  7 siblings, 1 reply; 13+ messages in thread
From: David Miller @ 2008-07-19  6:08 UTC (permalink / raw)
  To: vladislav.yasevich; +Cc: netdev, linux-sctp

From: Vlad Yasevich <vladislav.yasevich@hp.com>
Date: Sat, 19 Jul 2008 00:26:45 -0400

> This is a bunch of SCTP fixes that have accumlated over the past week or
> so. 

All applied, thanks Vlad.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATC] sctp: various fixes
  2008-07-19  6:08 ` [PATC] sctp: various fixes David Miller
@ 2008-07-20  5:40   ` David Miller
  2008-07-21 13:12     ` Vlad Yasevich
  0 siblings, 1 reply; 13+ messages in thread
From: David Miller @ 2008-07-20  5:40 UTC (permalink / raw)
  To: vladislav.yasevich; +Cc: netdev, linux-sctp

From: David Miller <davem@davemloft.net>
Date: Fri, 18 Jul 2008 23:08:33 -0700 (PDT)

> From: Vlad Yasevich <vladislav.yasevich@hp.com>
> Date: Sat, 19 Jul 2008 00:26:45 -0400
> 
> > This is a bunch of SCTP fixes that have accumlated over the past week or
> > so. 
> 
> All applied, thanks Vlad.

Vlad, I had to add the following fix to the tree in order
to unbreak the build when CONFIG_HIGHMEM is enabled.

highmem: Export totalhigh_pages.

Hash et al. sizing code in SCTP wants to make the
calculation totalram_pages - totalhigh_pages, just
like TCP.  But this requires an export for the
CONFIG_HIGHMEM case to work.

Signed-off-by: David S. Miller <davem@davemloft.net>

diff --git a/mm/highmem.c b/mm/highmem.c
index 7da4a7b..e16e152 100644
--- a/mm/highmem.c
+++ b/mm/highmem.c
@@ -40,6 +40,7 @@
 #ifdef CONFIG_HIGHMEM
 
 unsigned long totalhigh_pages __read_mostly;
+EXPORT_SYMBOL(totalhigh_pages);
 
 unsigned int nr_free_highpages (void)
 {

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATC] sctp: various fixes
  2008-07-20  5:40   ` David Miller
@ 2008-07-21 13:12     ` Vlad Yasevich
  2008-07-21 15:05       ` David Miller
  0 siblings, 1 reply; 13+ messages in thread
From: Vlad Yasevich @ 2008-07-21 13:12 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-sctp

David Miller wrote:
> From: David Miller <davem@davemloft.net>
> Date: Fri, 18 Jul 2008 23:08:33 -0700 (PDT)
> 
>> From: Vlad Yasevich <vladislav.yasevich@hp.com>
>> Date: Sat, 19 Jul 2008 00:26:45 -0400
>>
>>> This is a bunch of SCTP fixes that have accumlated over the past week or
>>> so. 
>> All applied, thanks Vlad.
> 
> Vlad, I had to add the following fix to the tree in order
> to unbreak the build when CONFIG_HIGHMEM is enabled.
> 

ahh...  since tcp isn't a module, it didn't trigger that.

Thanks Dave.  I didn't think about turning highmem off..

-vlad

> highmem: Export totalhigh_pages.
> 
> Hash et al. sizing code in SCTP wants to make the
> calculation totalram_pages - totalhigh_pages, just
> like TCP.  But this requires an export for the
> CONFIG_HIGHMEM case to work.
> 
> Signed-off-by: David S. Miller <davem@davemloft.net>
> 
> diff --git a/mm/highmem.c b/mm/highmem.c
> index 7da4a7b..e16e152 100644
> --- a/mm/highmem.c
> +++ b/mm/highmem.c
> @@ -40,6 +40,7 @@
>  #ifdef CONFIG_HIGHMEM
>  
>  unsigned long totalhigh_pages __read_mostly;
> +EXPORT_SYMBOL(totalhigh_pages);
>  
>  unsigned int nr_free_highpages (void)
>  {
> 


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATC] sctp: various fixes
  2008-07-21 13:12     ` Vlad Yasevich
@ 2008-07-21 15:05       ` David Miller
  2008-07-21 15:19         ` Vlad Yasevich
  0 siblings, 1 reply; 13+ messages in thread
From: David Miller @ 2008-07-21 15:05 UTC (permalink / raw)
  To: vladislav.yasevich; +Cc: netdev, linux-sctp

From: Vlad Yasevich <vladislav.yasevich@hp.com>
Date: Mon, 21 Jul 2008 09:12:21 -0400

> David Miller wrote:
> > From: David Miller <davem@davemloft.net>
> > Date: Fri, 18 Jul 2008 23:08:33 -0700 (PDT)
> > 
> >> From: Vlad Yasevich <vladislav.yasevich@hp.com>
> >> Date: Sat, 19 Jul 2008 00:26:45 -0400
> >>
> >>> This is a bunch of SCTP fixes that have accumlated over the past week or
> >>> so. 
> >> All applied, thanks Vlad.
> > 
> > Vlad, I had to add the following fix to the tree in order
> > to unbreak the build when CONFIG_HIGHMEM is enabled.
> > 
> 
> ahh...  since tcp isn't a module, it didn't trigger that.
> 
> Thanks Dave.  I didn't think about turning highmem off..

No problem, but the problematic case was turning highmem on :-)

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATC] sctp: various fixes
  2008-07-21 15:05       ` David Miller
@ 2008-07-21 15:19         ` Vlad Yasevich
  0 siblings, 0 replies; 13+ messages in thread
From: Vlad Yasevich @ 2008-07-21 15:19 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-sctp

David Miller wrote:
> From: Vlad Yasevich <vladislav.yasevich@hp.com>
> Date: Mon, 21 Jul 2008 09:12:21 -0400
> 
>> David Miller wrote:
>>> From: David Miller <davem@davemloft.net>
>>> Date: Fri, 18 Jul 2008 23:08:33 -0700 (PDT)
>>>
>>>> From: Vlad Yasevich <vladislav.yasevich@hp.com>
>>>> Date: Sat, 19 Jul 2008 00:26:45 -0400
>>>>
>>>>> This is a bunch of SCTP fixes that have accumlated over the past week or
>>>>> so. 
>>>> All applied, thanks Vlad.
>>> Vlad, I had to add the following fix to the tree in order
>>> to unbreak the build when CONFIG_HIGHMEM is enabled.
>>>
>> ahh...  since tcp isn't a module, it didn't trigger that.
>>
>> Thanks Dave.  I didn't think about turning highmem off..
> 
> No problem, but the problematic case was turning highmem on :-)
> 

argh.....

CONFIG_HIGHMEM=y
...
CONFIG_SCTP=y

Ran my tests in kvm and it's easier to build stuff in.

-vlad

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2008-07-21 15:19 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-07-19  4:26 [PATC] sctp: various fixes Vlad Yasevich
2008-07-19  4:26 ` [PATCH 1/7] sctp: Don't abort initialization when CONFIG_PROC_FS=n Vlad Yasevich
2008-07-19  4:26 ` [PATCH 2/7] sctp: Prevent uninitialized memory access Vlad Yasevich
2008-07-19  4:26 ` [PATCH 3/7] sctp: Support ipv6only AF_INET6 sockets Vlad Yasevich
2008-07-19  4:26 ` [PATCH 4/7] sctp: Do not leak memory on multiple listen() calls Vlad Yasevich
2008-07-19  4:26 ` [PATCH 5/7] sctp: Allow only 1 listening socket with SO_REUSEADDR Vlad Yasevich
2008-07-19  4:26 ` [PATCH 6/7] sctp: remove unnecessary byteshifting, calculate directly in big-endian Vlad Yasevich
2008-07-19  4:26 ` [PATCH 7/7] sctp: Update sctp global memory limit allocations Vlad Yasevich
2008-07-19  6:08 ` [PATC] sctp: various fixes David Miller
2008-07-20  5:40   ` David Miller
2008-07-21 13:12     ` Vlad Yasevich
2008-07-21 15:05       ` David Miller
2008-07-21 15:19         ` Vlad Yasevich

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).