Commit 17ce2cae authored by Jon Grimm's avatar Jon Grimm

Merge touki.austin.ibm.com:/home/jgrimm/bk/linux-2.5

into touki.austin.ibm.com:/home/jgrimm/bk/lksctp-2.5.work
parents 1eba1937 fd011af7
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
* Daisy Chang <daisyc@us.ibm.com> * Daisy Chang <daisyc@us.ibm.com>
* Sridhar Samudrala <sri@us.ibm.com> * Sridhar Samudrala <sri@us.ibm.com>
* Ardelle Fan <ardelle.fan@intel.com> * Ardelle Fan <ardelle.fan@intel.com>
* Ryan Layer <rmlayer@us.ibm.com>
* *
* Any bugs reported given to us we will try to fix... any fixes shared will * Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release. * be incorporated into the next SCTP release.
...@@ -311,6 +312,11 @@ void sctp_sysctl_unregister(void); ...@@ -311,6 +312,11 @@ void sctp_sysctl_unregister(void);
#else #else
static inline void sctp_sysctl_register(void) { return; } static inline void sctp_sysctl_register(void) { return; }
static inline void sctp_sysctl_unregister(void) { return; } static inline void sctp_sysctl_unregister(void) { return; }
static inline int sctp_sysctl_jiffies_ms(ctl_table *table, int __user *name, int nlen,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen, void **context) {
return -ENOSYS;
}
#endif #endif
/* Size of Supported Address Parameter for 'x' address types. */ /* Size of Supported Address Parameter for 'x' address types. */
...@@ -470,7 +476,7 @@ for (err = (sctp_errhdr_t *)((void *)chunk_hdr + \ ...@@ -470,7 +476,7 @@ for (err = (sctp_errhdr_t *)((void *)chunk_hdr + \
WORD_ROUND(ntohs(err->length));\ WORD_ROUND(ntohs(err->length));\
err = (sctp_errhdr_t *)((void *)err + \ err = (sctp_errhdr_t *)((void *)err + \
WORD_ROUND(ntohs(err->length)))) WORD_ROUND(ntohs(err->length))))
/* Round an int up to the next multiple of 4. */ /* Round an int up to the next multiple of 4. */
#define WORD_ROUND(s) (((s)+3)&~3) #define WORD_ROUND(s) (((s)+3)&~3)
...@@ -592,7 +598,7 @@ int static inline __sctp_style(const struct sock *sk, sctp_socket_type_t style) ...@@ -592,7 +598,7 @@ int static inline __sctp_style(const struct sock *sk, sctp_socket_type_t style)
/* Is the association in this state? */ /* Is the association in this state? */
#define sctp_state(asoc, state) __sctp_state((asoc), (SCTP_STATE_##state)) #define sctp_state(asoc, state) __sctp_state((asoc), (SCTP_STATE_##state))
int static inline __sctp_state(const struct sctp_association *asoc, int static inline __sctp_state(const struct sctp_association *asoc,
sctp_state_t state) sctp_state_t state)
{ {
return asoc->state == state; return asoc->state == state;
......
...@@ -281,7 +281,7 @@ struct sctp_association *sctp_association_init(struct sctp_association *asoc, ...@@ -281,7 +281,7 @@ struct sctp_association *sctp_association_init(struct sctp_association *asoc,
asoc->default_flags = sp->default_flags; asoc->default_flags = sp->default_flags;
asoc->default_context = sp->default_context; asoc->default_context = sp->default_context;
asoc->default_timetolive = sp->default_timetolive; asoc->default_timetolive = sp->default_timetolive;
return asoc; return asoc;
fail_init: fail_init:
...@@ -384,7 +384,7 @@ void sctp_assoc_set_primary(struct sctp_association *asoc, ...@@ -384,7 +384,7 @@ void sctp_assoc_set_primary(struct sctp_association *asoc,
if (transport->active) if (transport->active)
asoc->peer.active_path = transport; asoc->peer.active_path = transport;
/* /*
* SFR-CACC algorithm: * SFR-CACC algorithm:
* Upon the receipt of a request to change the primary * Upon the receipt of a request to change the primary
* destination address, on the data structure for the new * destination address, on the data structure for the new
...@@ -793,6 +793,26 @@ struct sctp_transport *sctp_assoc_is_match(struct sctp_association *asoc, ...@@ -793,6 +793,26 @@ struct sctp_transport *sctp_assoc_is_match(struct sctp_association *asoc,
return transport; return transport;
} }
/* Is this a live association structure. */
int sctp_assoc_valid(struct sock *sk, struct sctp_association *asoc)
{
/* First, verify that this is a kernel address. */
if (!sctp_is_valid_kaddr((unsigned long) asoc))
return 0;
/* Verify that this _is_ an sctp_association
* data structure and if so, that the socket matches.
*/
if (SCTP_ASSOC_EYECATCHER != asoc->eyecatcher)
return 0;
if (asoc->base.sk != sk)
return 0;
/* The association is valid. */
return 1;
}
/* Do delayed input processing. This is scheduled by sctp_rcv(). */ /* Do delayed input processing. This is scheduled by sctp_rcv(). */
static void sctp_assoc_bh_rcv(struct sctp_association *asoc) static void sctp_assoc_bh_rcv(struct sctp_association *asoc)
{ {
...@@ -801,7 +821,6 @@ static void sctp_assoc_bh_rcv(struct sctp_association *asoc) ...@@ -801,7 +821,6 @@ static void sctp_assoc_bh_rcv(struct sctp_association *asoc)
struct sock *sk; struct sock *sk;
struct sctp_inq *inqueue; struct sctp_inq *inqueue;
int state, subtype; int state, subtype;
sctp_assoc_t associd = sctp_assoc2id(asoc);
int error = 0; int error = 0;
/* The association should be held so we should be safe. */ /* The association should be held so we should be safe. */
...@@ -831,7 +850,7 @@ static void sctp_assoc_bh_rcv(struct sctp_association *asoc) ...@@ -831,7 +850,7 @@ static void sctp_assoc_bh_rcv(struct sctp_association *asoc)
/* Check to see if the association is freed in response to /* Check to see if the association is freed in response to
* the incoming chunk. If so, get out of the while loop. * the incoming chunk. If so, get out of the while loop.
*/ */
if (!sctp_id2assoc(sk, associd)) if (!sctp_assoc_valid(sk, asoc))
break; break;
/* If there is an error on chunk, discard this packet. */ /* If there is an error on chunk, discard this packet. */
......
...@@ -4500,13 +4500,21 @@ struct sctp_packet *sctp_ootb_pkt_new(const struct sctp_association *asoc, ...@@ -4500,13 +4500,21 @@ struct sctp_packet *sctp_ootb_pkt_new(const struct sctp_association *asoc,
if (asoc) { if (asoc) {
vtag = asoc->peer.i.init_tag; vtag = asoc->peer.i.init_tag;
} else { } else {
/* Special case the INIT as there is no vtag yet. */ /* Special case the INIT and stale COOKIE_ECHO as there is no
if (SCTP_CID_INIT == chunk->chunk_hdr->type) { * vtag yet.
*/
switch(chunk->chunk_hdr->type) {
case SCTP_CID_INIT:
{
sctp_init_chunk_t *init; sctp_init_chunk_t *init;
init = (sctp_init_chunk_t *)chunk->chunk_hdr; init = (sctp_init_chunk_t *)chunk->chunk_hdr;
vtag = ntohl(init->init_hdr.init_tag); vtag = ntohl(init->init_hdr.init_tag);
} else { break;
}
default:
vtag = ntohl(chunk->sctp_hdr->vtag); vtag = ntohl(chunk->sctp_hdr->vtag);
break;
} }
} }
...@@ -4557,6 +4565,12 @@ void sctp_send_stale_cookie_err(const struct sctp_endpoint *ep, ...@@ -4557,6 +4565,12 @@ void sctp_send_stale_cookie_err(const struct sctp_endpoint *ep,
if (err_chunk) { if (err_chunk) {
packet = sctp_ootb_pkt_new(asoc, chunk); packet = sctp_ootb_pkt_new(asoc, chunk);
if (packet) { if (packet) {
sctp_signed_cookie_t *cookie;
/* Override the OOTB vtag from the cookie. */
cookie = chunk->subh.cookie_hdr;
packet->vtag = cookie->c.peer_vtag;
/* Set the skb to the belonging sock for accounting. */ /* Set the skb to the belonging sock for accounting. */
err_chunk->skb->sk = ep->base.sk; err_chunk->skb->sk = ep->base.sk;
sctp_packet_append_chunk(packet, err_chunk); sctp_packet_append_chunk(packet, err_chunk);
......
...@@ -101,6 +101,9 @@ static char *sctp_hmac_alg = SCTP_COOKIE_HMAC_ALG; ...@@ -101,6 +101,9 @@ static char *sctp_hmac_alg = SCTP_COOKIE_HMAC_ALG;
extern kmem_cache_t *sctp_bucket_cachep; extern kmem_cache_t *sctp_bucket_cachep;
extern int sctp_assoc_valid(struct sock *sk, struct sctp_association *asoc);
/* Look up the association by its id. If this is not a UDP-style /* Look up the association by its id. If this is not a UDP-style
* socket, the ID field is always ignored. * socket, the ID field is always ignored.
*/ */
...@@ -110,32 +113,24 @@ struct sctp_association *sctp_id2assoc(struct sock *sk, sctp_assoc_t id) ...@@ -110,32 +113,24 @@ struct sctp_association *sctp_id2assoc(struct sock *sk, sctp_assoc_t id)
/* If this is not a UDP-style socket, assoc id should be ignored. */ /* If this is not a UDP-style socket, assoc id should be ignored. */
if (!sctp_style(sk, UDP)) { if (!sctp_style(sk, UDP)) {
/* Return NULL if the socket state is not ESTABLISHED. It /* Return NULL if the socket state is not ESTABLISHED. It
* could be a TCP-style listening socket or a socket which * could be a TCP-style listening socket or a socket which
* hasn't yet called connect() to establish an association. * hasn't yet called connect() to establish an association.
*/ */
if (!sctp_sstate(sk, ESTABLISHED)) if (!sctp_sstate(sk, ESTABLISHED))
return NULL; return NULL;
/* Get the first and the only association from the list. */ /* Get the first and the only association from the list. */
if (!list_empty(&sctp_sk(sk)->ep->asocs)) if (!list_empty(&sctp_sk(sk)->ep->asocs))
asoc = list_entry(sctp_sk(sk)->ep->asocs.next, asoc = list_entry(sctp_sk(sk)->ep->asocs.next,
struct sctp_association, asocs); struct sctp_association, asocs);
return asoc; return asoc;
} }
/* First, verify that this is a kernel address. */ /* Otherwise this is a UDP-style socket. */
if (sctp_is_valid_kaddr((unsigned long) id)) { asoc = (struct sctp_association *)id;
struct sctp_association *temp; if (!sctp_assoc_valid(sk, asoc))
return NULL;
/* Verify that this _is_ an sctp_association
* data structure and if so, that the socket matches.
*/
temp = (struct sctp_association *)id;
if ((SCTP_ASSOC_EYECATCHER == temp->eyecatcher) &&
(temp->base.sk == sk))
asoc = temp;
}
return asoc; return asoc;
} }
...@@ -1456,7 +1451,7 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char *optval, ...@@ -1456,7 +1451,7 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char *optval,
* spp_pathmaxrxt - This contains the maximum number of * spp_pathmaxrxt - This contains the maximum number of
* retransmissions before this address shall be * retransmissions before this address shall be
* considered unreachable. * considered unreachable.
*/ */
static int sctp_setsockopt_peer_addr_params(struct sock *sk, static int sctp_setsockopt_peer_addr_params(struct sock *sk,
char *optval, int optlen) char *optval, int optlen)
{ {
...@@ -2430,7 +2425,7 @@ static int sctp_getsockopt_peeloff(struct sock *sk, int len, char *optval, int * ...@@ -2430,7 +2425,7 @@ static int sctp_getsockopt_peeloff(struct sock *sk, int len, char *optval, int *
* spp_pathmaxrxt - This contains the maximum number of * spp_pathmaxrxt - This contains the maximum number of
* retransmissions before this address shall be * retransmissions before this address shall be
* considered unreachable. * considered unreachable.
*/ */
static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len, static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len,
char *optval, int *optlen) char *optval, int *optlen)
{ {
......
/* SCTP kernel reference Implementation /* SCTP kernel reference Implementation
* Copyright (c) 2002 International Business Machines Corp. * Copyright (c) 2002 International Business Machines Corp.
* Copyright (c) 2002 Intel Corp. * Copyright (c) 2002 Intel Corp.
* *
* This file is part of the SCTP kernel reference Implementation * This file is part of the SCTP kernel reference Implementation
* *
* Sysctl related interfaces for SCTP. * Sysctl related interfaces for SCTP.
* *
* The SCTP reference implementation is free software; * The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of * you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by * the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option) * the Free Software Foundation; either version 2, or (at your option)
* any later version. * any later version.
* *
* The SCTP reference implementation is distributed in the hope that it * The SCTP reference implementation is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied * will be useful, but WITHOUT ANY WARRANTY; without even the implied
* ************************ * ************************
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to * along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330, * the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
* *
* Please send any bug reports or fixes you make to the * Please send any bug reports or fixes you make to the
* email address(es): * email address(es):
* lksctp developers <lksctp-developers@lists.sourceforge.net> * lksctp developers <lksctp-developers@lists.sourceforge.net>
* *
* Or submit a bug report through the following website: * Or submit a bug report through the following website:
* http://www.sf.net/projects/lksctp * http://www.sf.net/projects/lksctp
* *
* Written or modified by: * Written or modified by:
* Mingqin Liu <liuming@us.ibm.com> * Mingqin Liu <liuming@us.ibm.com>
* Jon Grimm <jgrimm@us.ibm.com> * Jon Grimm <jgrimm@us.ibm.com>
* Ardelle Fan <ardelle.fan@intel.com> * Ardelle Fan <ardelle.fan@intel.com>
* Ryan Layer <rmlayer@us.ibm.com>
* *
* Any bugs reported given to us we will try to fix... any fixes shared will * Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release. * be incorporated into the next SCTP release.
...@@ -42,42 +43,54 @@ ...@@ -42,42 +43,54 @@
#include <net/sctp/structs.h> #include <net/sctp/structs.h>
#include <linux/sysctl.h> #include <linux/sysctl.h>
static ctl_handler sctp_sysctl_jiffies_ms;
static long rto_timer_min = 0;
static long rto_timer_max = 86400000; /* One day */
static ctl_table sctp_table[] = { static ctl_table sctp_table[] = {
{ {
.ctl_name = NET_SCTP_RTO_INITIAL, .ctl_name = NET_SCTP_RTO_INITIAL,
.procname = "rto_initial", .procname = "rto_initial",
.data = &sctp_rto_initial, .data = &sctp_rto_initial,
.maxlen = sizeof(int), .maxlen = sizeof(long),
.mode = 0644, .mode = 0644,
.proc_handler = &proc_dointvec_jiffies, .proc_handler = &proc_doulongvec_ms_jiffies_minmax,
.strategy = &sysctl_jiffies .strategy = &sctp_sysctl_jiffies_ms,
.extra1 = &rto_timer_min,
.extra2 = &rto_timer_max
}, },
{ {
.ctl_name = NET_SCTP_RTO_MIN, .ctl_name = NET_SCTP_RTO_MIN,
.procname = "rto_min", .procname = "rto_min",
.data = &sctp_rto_min, .data = &sctp_rto_min,
.maxlen = sizeof(int), .maxlen = sizeof(long),
.mode = 0644, .mode = 0644,
.proc_handler = &proc_dointvec_jiffies, .proc_handler = &proc_doulongvec_ms_jiffies_minmax,
.strategy = &sysctl_jiffies .strategy = &sctp_sysctl_jiffies_ms,
.extra1 = &rto_timer_min,
.extra2 = &rto_timer_max
}, },
{ {
.ctl_name = NET_SCTP_RTO_MAX, .ctl_name = NET_SCTP_RTO_MAX,
.procname = "rto_max", .procname = "rto_max",
.data = &sctp_rto_max, .data = &sctp_rto_max,
.maxlen = sizeof(int), .maxlen = sizeof(long),
.mode = 0644, .mode = 0644,
.proc_handler = &proc_dointvec_jiffies, .proc_handler = &proc_doulongvec_ms_jiffies_minmax,
.strategy = &sysctl_jiffies .strategy = &sctp_sysctl_jiffies_ms,
.extra1 = &rto_timer_min,
.extra2 = &rto_timer_max
}, },
{ {
.ctl_name = NET_SCTP_VALID_COOKIE_LIFE, .ctl_name = NET_SCTP_VALID_COOKIE_LIFE,
.procname = "valid_cookie_life", .procname = "valid_cookie_life",
.data = &sctp_valid_cookie_life, .data = &sctp_valid_cookie_life,
.maxlen = sizeof(int), .maxlen = sizeof(long),
.mode = 0644, .mode = 0644,
.proc_handler = &proc_dointvec_jiffies, .proc_handler = &proc_doulongvec_ms_jiffies_minmax,
.strategy = &sysctl_jiffies .strategy = &sctp_sysctl_jiffies_ms,
.extra1 = &rto_timer_min,
.extra2 = &rto_timer_max
}, },
{ {
.ctl_name = NET_SCTP_MAX_BURST, .ctl_name = NET_SCTP_MAX_BURST,
...@@ -183,3 +196,37 @@ void sctp_sysctl_unregister(void) ...@@ -183,3 +196,37 @@ void sctp_sysctl_unregister(void)
{ {
unregister_sysctl_table(sctp_sysctl_header); unregister_sysctl_table(sctp_sysctl_header);
} }
/* Strategy function to convert jiffies to milliseconds. */
static int sctp_sysctl_jiffies_ms(ctl_table *table, int __user *name, int nlen,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen, void **context) {
if (oldval) {
size_t olen;
if (oldlenp) {
if (get_user(olen, oldlenp))
return -EFAULT;
if (olen != sizeof (int))
return -EINVAL;
}
if (put_user((*(int *)(table->data) / HZ) * 1000,
(int *)oldval) ||
(oldlenp && put_user(sizeof (int), oldlenp)))
return -EFAULT;
}
if (newval && newlen) {
int new;
if (newlen != sizeof (int))
return -EINVAL;
if (get_user(new, (int *)newval))
return -EFAULT;
*(int *)(table->data) = (new * HZ) * 1000;
}
return 1;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment