lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Thu, 03 Jun 2010 15:43:50 +0800
From:	Wei Yongjun <yjwei@...fujitsu.com>
To:	Yaogong Wang <ywang15@...u.edu>
CC:	linux-sctp@...r.kernel.org,
	Vlad Yasevich <vladislav.yasevich@...com>,
	Sridhar Samudrala <sri@...ibm.com>,
	linux-kernel@...r.kernel.org
Subject: Re: [PATCH 2/6] sctp multistream scheduling: provide pluggable SCTP
 	scheduling framework


> Provide a general interface for implementing new SCTP multistream
> scheduling algorithms as kernel modules.
>
>   

after apply this patch, the SCTP will be broken, this will
broken git bisect.

> Signed-off-by: Yaogong Wang <ywang15@...u.edu>
> ---
> diff -uprN -X linux-2.6.32.8/Documentation/dontdiff
> p1/include/net/sctp/structs.h p2/include/net/sctp/structs.h
> --- p1/include/net/sctp/structs.h	2010-05-28 10:33:12.000000000 -0700
> +++ p2/include/net/sctp/structs.h	2010-06-02 13:02:14.000000000 -0700
> @@ -1158,7 +1158,7 @@ struct sctp_outq {
>  	struct sctp_association *asoc;
>
>  	/* Data pending that has never been transmitted.  */
> -	struct list_head out_chunk_list;
> +	struct list_head *out_chunk_list;
>
>  	unsigned out_qlen;	/* Total length of queued data chunks. */
>
> @@ -1199,7 +1199,7 @@ struct sctp_outq {
>  	char malloced;
>  };
>
> -void sctp_outq_init(struct sctp_association *, struct sctp_outq *);
> +int sctp_outq_init(struct sctp_association *, struct sctp_outq *, gfp_t gfp);
>  void sctp_outq_teardown(struct sctp_outq *);
>  void sctp_outq_free(struct sctp_outq*);
>  int sctp_outq_tail(struct sctp_outq *, struct sctp_chunk *chunk);
> diff -uprN -X linux-2.6.32.8/Documentation/dontdiff
> p1/net/sctp/Makefile p2/net/sctp/Makefile
> --- p1/net/sctp/Makefile	2010-05-28 10:05:50.000000000 -0700
> +++ p2/net/sctp/Makefile	2010-06-02 12:55:13.000000000 -0700
> @@ -9,7 +9,7 @@ sctp-y := sm_statetable.o sm_statefuns.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 auth.o
> +	  output.o input.o debug.o ssnmap.o auth.o sched.o
>
>  sctp-$(CONFIG_SCTP_DBG_OBJCNT) += objcnt.o
>  sctp-$(CONFIG_PROC_FS) += proc.o
> diff -uprN -X linux-2.6.32.8/Documentation/dontdiff
> p1/net/sctp/associola.c p2/net/sctp/associola.c
> --- p1/net/sctp/associola.c	2010-05-28 10:05:50.000000000 -0700
> +++ p2/net/sctp/associola.c	2010-06-02 12:56:23.000000000 -0700
> @@ -185,6 +185,9 @@ static struct sctp_association *sctp_ass
>  	asoc->max_init_timeo =
>  		 msecs_to_jiffies(sp->initmsg.sinit_max_init_timeo);
>
> +	/* Multistream scheduling  */
> +	asoc->sched_ops = sp->sched_ops;
> +
>  	/* Allocate storage for the ssnmap after the inbound and outbound
>  	 * streams have been negotiated during Init.
>  	 */
> @@ -280,7 +283,9 @@ static struct sctp_association *sctp_ass
>  	sctp_inq_set_th_handler(&asoc->base.inqueue, sctp_assoc_bh_rcv);
>
>  	/* Create an output queue.  */
> -	sctp_outq_init(asoc, &asoc->outqueue);
> +	err = sctp_outq_init(asoc, &asoc->outqueue, gfp);
> +	if (err)
> +		goto fail_init;
>
>  	if (!sctp_ulpq_init(&asoc->ulpq, asoc))
>  		goto fail_init;
> diff -uprN -X linux-2.6.32.8/Documentation/dontdiff
> p1/net/sctp/outqueue.c p2/net/sctp/outqueue.c
> --- p1/net/sctp/outqueue.c	2010-05-28 10:05:50.000000000 -0700
> +++ p2/net/sctp/outqueue.c	2010-06-02 12:55:13.000000000 -0700
> @@ -73,38 +73,6 @@ static void sctp_generate_fwdtsn(struct
>
>  static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout);
>
> -/* Add data to the front of the queue. */
> -static inline void sctp_outq_head_data(struct sctp_outq *q,
> -					struct sctp_chunk *ch)
> -{
> -	list_add(&ch->list, &q->out_chunk_list);
> -	q->out_qlen += ch->skb->len;
> -	return;
> -}
> -
> -/* Take data from the front of the queue. */
> -static inline struct sctp_chunk *sctp_outq_dequeue_data(struct sctp_outq *q)
> -{
> -	struct sctp_chunk *ch = NULL;
> -
> -	if (!list_empty(&q->out_chunk_list)) {
> -		struct list_head *entry = q->out_chunk_list.next;
> -
> -		ch = list_entry(entry, struct sctp_chunk, list);
> -		list_del_init(entry);
> -		q->out_qlen -= ch->skb->len;
> -	}
> -	return ch;
> -}
> -/* Add data chunk to the end of the queue. */
> -static inline void sctp_outq_tail_data(struct sctp_outq *q,
> -				       struct sctp_chunk *ch)
> -{
> -	list_add_tail(&ch->list, &q->out_chunk_list);
> -	q->out_qlen += ch->skb->len;
> -	return;
> -}
> -
>  /*
>   * SFR-CACC algorithm:
>   * D) If count_of_newacks is greater than or equal to 2
> @@ -201,10 +169,15 @@ static inline int sctp_cacc_skip(struct
>   * You still need to define handlers if you really want to DO
>   * something with this structure...
>   */
> -void sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q)
> +int sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q,
> +			gfp_t gfp)
>  {
> -	q->asoc = asoc;
> -	INIT_LIST_HEAD(&q->out_chunk_list);
> +	int err = 0;
> +
> +	q->asoc = asoc;
> +	err = q->asoc->sched_ops->init(q, gfp);
> +	if (err)
> +		goto fail_init;
>  	INIT_LIST_HEAD(&q->control_chunk_list);
>  	INIT_LIST_HEAD(&q->retransmit);
>  	INIT_LIST_HEAD(&q->sacked);
> @@ -217,6 +190,9 @@ void sctp_outq_init(struct sctp_associat
>
>  	q->malloced = 0;
>  	q->out_qlen = 0;
> +
> +fail_init:
> +	return err;
>  }
>
>  /* Free the outqueue structure and any related pending chunks.
> @@ -267,7 +243,7 @@ void sctp_outq_teardown(struct sctp_outq
>  	}
>
>  	/* Throw away any leftover data chunks. */
> -	while ((chunk = sctp_outq_dequeue_data(q)) != NULL) {
> +	while ((chunk = q->asoc->sched_ops->dequeue_data(q)) != NULL) {
>   

why not use sctp_outq_dequeue_data() as help function
instead of direct using q->asoc->sched_ops->dequeue_data()?
and also the others.

>  		/* Mark as send failure. */
>  		sctp_chunk_fail(chunk, q->error);
> @@ -289,6 +265,8 @@ void sctp_outq_free(struct sctp_outq *q)
>  	/* Throw away leftover chunks. */
>  	sctp_outq_teardown(q);
>
> +	q->asoc->sched_ops->release(q);
> +
>  	/* If we were kmalloc()'d, free the memory.  */
>  	if (q->malloced)
>  		kfree(q);
> @@ -334,7 +312,7 @@ int sctp_outq_tail(struct sctp_outq *q,
>  			  sctp_cname(SCTP_ST_CHUNK(chunk->chunk_hdr->type))
>  			  : "Illegal Chunk");
>
> -			sctp_outq_tail_data(q, chunk);
> +			q->asoc->sched_ops->enqueue_tail_data(q, chunk);
>  			if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED)
>  				SCTP_INC_STATS(SCTP_MIB_OUTUNORDERCHUNKS);
>  			else
> @@ -922,7 +900,7 @@ static int sctp_outq_flush(struct sctp_o
>  		}
>
>  		/* Finally, transmit new packets.  */
> -		while ((chunk = sctp_outq_dequeue_data(q)) != NULL) {
> +		while ((chunk = q->asoc->sched_ops->dequeue_data(q)) != NULL) {
>  			/* RFC 2960 6.5 Every DATA chunk MUST carry a valid
>  			 * stream identifier.
>  			 */
> @@ -996,7 +974,7 @@ static int sctp_outq_flush(struct sctp_o
>  					"not transmit TSN: 0x%x, status: %d\n",
>  					ntohl(chunk->subh.data_hdr->tsn),
>  					status);
> -				sctp_outq_head_data(q, chunk);
> +				q->asoc->sched_ops->enqueue_head_data(q, chunk);
>  				goto sctp_flush_out;
>  				break;
>
> @@ -1252,7 +1230,7 @@ int sctp_outq_sack(struct sctp_outq *q,
>  	/* See if all chunks are acked.
>  	 * Make sure the empty queue handler will get run later.
>  	 */
> -	q->empty = (list_empty(&q->out_chunk_list) &&
> +	q->empty = (q->asoc->sched_ops->is_empty(q) &&
>  		    list_empty(&q->retransmit));
>  	if (!q->empty)
>  		goto finish;
> diff -uprN -X linux-2.6.32.8/Documentation/dontdiff
> p1/net/sctp/sched.c p2/net/sctp/sched.c
> --- p1/net/sctp/sched.c	1969-12-31 16:00:00.000000000 -0800
> +++ p2/net/sctp/sched.c	2010-06-02 12:59:40.000000000 -0700
> @@ -0,0 +1,116 @@
> +/*
> + * Plugable SCTP scheduling support and FCFS
> + * Based on ideas from pluggable TCP congestion control.
> + *
> + */
> +
> +#include <linux/module.h>
> +#include <linux/types.h>
> +#include <linux/list.h>
> +#include <net/sctp/sctp.h>
> +
> +static DEFINE_SPINLOCK(sctp_sched_list_lock);
> +static LIST_HEAD(sctp_sched_list);
> +
> +/* Simple linear search, don't expect many entries! */
> +static struct sctp_sched_ops *sctp_sched_find(const char *name)
> +{
> +	struct sctp_sched_ops *e;
> +
> +	list_for_each_entry_rcu(e, &sctp_sched_list, list) {
> +		if (strcmp(e->name, name) == 0)
> +			return e;
> +	}
> +
> +	return NULL;
> +}
> +
> +/*
> + * Attach new scheduling algorithm to the list
> + * of available options.
> + */
> +int sctp_register_sched(struct sctp_sched_ops *sched)
> +{
> +	int ret = 0;
> +
> +	/* all algorithms must implement enqueue and dequeue ops */
> +	if (!sched->init || !sched->release || !sched->is_empty
> +		|| !sched->enqueue_head_data || !sched->enqueue_tail_data
> +		|| !sched->dequeue_data) {
> +		printk(KERN_ERR "SCTP %s does not implement required ops\n",
> +		       sched->name);
> +		return -EINVAL;
> +	}
> +
> +	spin_lock(&sctp_sched_list_lock);
> +	if (sctp_sched_find(sched->name)) {
> +		printk(KERN_NOTICE "SCTP %s already registered\n", sched->name);
> +		ret = -EEXIST;
> +	} else {
> +		list_add_tail_rcu(&sched->list, &sctp_sched_list);
> +		printk(KERN_INFO "SCTP %s registered\n", sched->name);
> +	}
> +	spin_unlock(&sctp_sched_list_lock);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(sctp_register_sched);
> +
> +/*
> + * Remove scheduling algorithm, called from
> + * the module's remove function.  Module ref counts are used
> + * to ensure that this can't be done till all sockets using
> + * that method are closed.
> + */
> +void sctp_unregister_sched(struct sctp_sched_ops *sched)
> +{
> +	spin_lock(&sctp_sched_list_lock);
> +	list_del_rcu(&sched->list);
> +	spin_unlock(&sctp_sched_list_lock);
> +}
> +EXPORT_SYMBOL_GPL(sctp_unregister_sched);
> +
> +/* Manage refcounts on socket close. */
> +void sctp_cleanup_sched(struct sock *sk)
> +{
> +	module_put(sctp_sk(sk)->sched_ops->owner);
> +}
> +
> +/* Change scheduling algorithm for socket */
> +int sctp_set_sched(struct sock *sk, const char *name)
> +{
> +	struct sctp_sock *sp = sctp_sk(sk);
> +	struct sctp_sched_ops *sched;
> +	int err = 0;
> +
> +	rcu_read_lock();
> +	sched = sctp_sched_find(name);
> +
> +	/* no change asking for existing value */
> +	if (sched == sp->sched_ops)
> +		goto out;
> +
> +#ifdef CONFIG_MODULES
> +	/* not found attempt to autoload module */
> +	if (!sched && capable(CAP_NET_ADMIN)) {
> +		rcu_read_unlock();
> +		request_module("sctp_%s", name);
> +		rcu_read_lock();
> +		sched = sctp_sched_find(name);
> +	}
> +#endif
> +	if (!sched)
> +		err = -ENOENT;
> +
> +	else if (!try_module_get(sched->owner))
> +		err = -EBUSY;
> +
> +	else {
> +		sctp_cleanup_sched(sk);
> +		sp->sched_ops = sched;
> +	}
> +out:
> +	rcu_read_unlock();
> +	return err;
> +}
> +
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sctp" in
> the body of a message to majordomo@...r.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>
>   
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ