* [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