diff options
Diffstat (limited to 'net/sctp/chunk.c')
| -rw-r--r-- | net/sctp/chunk.c | 52 | 
1 files changed, 27 insertions, 25 deletions
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c index 6c8556459a7..158701da2d3 100644 --- a/net/sctp/chunk.c +++ b/net/sctp/chunk.c @@ -18,23 +18,16 @@   * See the GNU General Public License for more details.   *   * You should have received a copy of the GNU General Public License - * along with GNU CC; see the file COPYING.  If not, write to - * the Free Software Foundation, 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * along with GNU CC; see the file COPYING.  If not, see + * <http://www.gnu.org/licenses/>.   *   * Please send any bug reports or fixes you make to the   * email address(es): - *    lksctp developers <lksctp-developers@lists.sourceforge.net> - * - * Or submit a bug report through the following website: - *    http://www.sf.net/projects/lksctp + *    lksctp developers <linux-sctp@vger.kernel.org>   *   * Written or modified by:   *    Jon Grimm             <jgrimm@us.ibm.com>   *    Sridhar Samudrala     <sri@us.ibm.com> - * - * Any bugs reported given to us we will try to fix... any fixes shared will - * be incorporated into the next SCTP release.   */  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -66,7 +59,7 @@ static void sctp_datamsg_init(struct sctp_datamsg *msg)  }  /* Allocate and initialize datamsg. */ -SCTP_STATIC struct sctp_datamsg *sctp_datamsg_new(gfp_t gfp) +static struct sctp_datamsg *sctp_datamsg_new(gfp_t gfp)  {  	struct sctp_datamsg *msg;  	msg = kmalloc(sizeof(struct sctp_datamsg), gfp); @@ -183,7 +176,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,  	msg = sctp_datamsg_new(GFP_KERNEL);  	if (!msg) -		return NULL; +		return ERR_PTR(-ENOMEM);  	/* Note: Calculate this outside of the loop, so that all fragments  	 * have the same expiration. @@ -193,20 +186,21 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,  		msg->expires_at = jiffies +  				    msecs_to_jiffies(sinfo->sinfo_timetolive);  		msg->can_abandon = 1; -		SCTP_DEBUG_PRINTK("%s: msg:%p expires_at: %ld jiffies:%ld\n", -				  __func__, msg, msg->expires_at, jiffies); + +		pr_debug("%s: msg:%p expires_at:%ld jiffies:%ld\n", __func__, +			 msg, msg->expires_at, jiffies);  	}  	/* This is the biggest possible DATA chunk that can fit into  	 * the packet  	 */ -	max_data = asoc->pathmtu - +	max_data = (asoc->pathmtu -  		sctp_sk(asoc->base.sk)->pf->af->net_header_len - -		sizeof(struct sctphdr) - sizeof(struct sctp_data_chunk); +		sizeof(struct sctphdr) - sizeof(struct sctp_data_chunk)) & ~3;  	max = asoc->frag_point;  	/* If the the peer requested that we authenticate DATA chunks -	 * we need to accound for bundling of the AUTH chunks along with +	 * we need to account for bundling of the AUTH chunks along with  	 * DATA.  	 */  	if (sctp_auth_send_cid(SCTP_CID_DATA, asoc)) { @@ -257,10 +251,10 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,  	offset = 0;  	if ((whole > 1) || (whole && over)) -		SCTP_INC_STATS_USER(SCTP_MIB_FRAGUSRMSGS); +		SCTP_INC_STATS_USER(sock_net(asoc->base.sk), SCTP_MIB_FRAGUSRMSGS);  	/* Create chunks for all the full sized DATA chunks. */ -	for (i=0, len=first_len; i < whole; i++) { +	for (i = 0, len = first_len; i < whole; i++) {  		frag = SCTP_DATA_MIDDLE_FRAG;  		if (0 == i) @@ -280,11 +274,14 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,  		chunk = sctp_make_datafrag_empty(asoc, sinfo, len, frag, 0); -		if (!chunk) +		if (!chunk) { +			err = -ENOMEM;  			goto errout; +		} +  		err = sctp_user_addto_chunk(chunk, offset, len, msgh->msg_iov);  		if (err < 0) -			goto errout; +			goto errout_chunk_free;  		offset += len; @@ -315,16 +312,18 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,  		chunk = sctp_make_datafrag_empty(asoc, sinfo, over, frag, 0); -		if (!chunk) +		if (!chunk) { +			err = -ENOMEM;  			goto errout; +		} -		err = sctp_user_addto_chunk(chunk, offset, over,msgh->msg_iov); +		err = sctp_user_addto_chunk(chunk, offset, over, msgh->msg_iov);  		/* Put the chunk->skb back into the form expected by send.  */  		__skb_pull(chunk->skb, (__u8 *)chunk->chunk_hdr  			   - (__u8 *)chunk->skb->data);  		if (err < 0) -			goto errout; +			goto errout_chunk_free;  		sctp_datamsg_assign(msg, chunk);  		list_add_tail(&chunk->frag_list, &msg->chunks); @@ -332,6 +331,9 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,  	return msg; +errout_chunk_free: +	sctp_chunk_free(chunk); +  errout:  	list_for_each_safe(pos, temp, &msg->chunks) {  		list_del_init(pos); @@ -339,7 +341,7 @@ errout:  		sctp_chunk_free(chunk);  	}  	sctp_datamsg_put(msg); -	return NULL; +	return ERR_PTR(err);  }  /* Check whether this message has expired. */  | 
