diff options
Diffstat (limited to 'net/sctp/sm_make_chunk.c')
| -rw-r--r-- | net/sctp/sm_make_chunk.c | 147 | 
1 files changed, 68 insertions, 79 deletions
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index d244a23ab8d..ae0e616a7ca 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -23,9 +23,8 @@   * 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): @@ -79,6 +78,8 @@ static int sctp_process_param(struct sctp_association *asoc,  			      gfp_t gfp);  static void *sctp_addto_param(struct sctp_chunk *chunk, int len,  			      const void *data); +static void  *sctp_addto_chunk_fixed(struct sctp_chunk *, int len, +				     const void *data);  /* Control chunk destructor */  static void sctp_control_release_owner(struct sk_buff *skb) @@ -218,6 +219,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,  			     gfp_t gfp, int vparam_len)  {  	struct net *net = sock_net(asoc->base.sk); +	struct sctp_endpoint *ep = asoc->ep;  	sctp_inithdr_t init;  	union sctp_params addrs;  	size_t chunksize; @@ -277,7 +279,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,  	chunksize += vparam_len;  	/* Account for AUTH related parameters */ -	if (net->sctp.auth_enable) { +	if (ep->auth_enable) {  		/* Add random parameter length*/  		chunksize += sizeof(asoc->c.auth_random); @@ -362,7 +364,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,  	}  	/* Add SCTP-AUTH chunks to the parameter list */ -	if (net->sctp.auth_enable) { +	if (ep->auth_enable) {  		sctp_addto_chunk(retval, sizeof(asoc->c.auth_random),  				 asoc->c.auth_random);  		if (auth_hmacs) @@ -1297,6 +1299,13 @@ struct sctp_chunk *sctp_make_auth(const struct sctp_association *asoc)  /* Turn an skb into a chunk.   * FIXME: Eventually move the structure directly inside the skb->cb[]. + * + * sctpimpguide-05.txt Section 2.8.2 + * M1) Each time a new DATA chunk is transmitted + * set the 'TSN.Missing.Report' count for that TSN to 0. The + * 'TSN.Missing.Report' count will be used to determine missing chunks + * and when to fast retransmit. + *   */  struct sctp_chunk *sctp_chunkify(struct sk_buff *skb,  			    const struct sctp_association *asoc, @@ -1314,29 +1323,9 @@ struct sctp_chunk *sctp_chunkify(struct sk_buff *skb,  	INIT_LIST_HEAD(&retval->list);  	retval->skb		= skb;  	retval->asoc		= (struct sctp_association *)asoc; -	retval->has_tsn		= 0; -	retval->has_ssn         = 0; -	retval->rtt_in_progress	= 0; -	retval->sent_at		= 0;  	retval->singleton	= 1; -	retval->end_of_packet	= 0; -	retval->ecn_ce_done	= 0; -	retval->pdiscard	= 0; - -	/* sctpimpguide-05.txt Section 2.8.2 -	 * M1) Each time a new DATA chunk is transmitted -	 * set the 'TSN.Missing.Report' count for that TSN to 0. The -	 * 'TSN.Missing.Report' count will be used to determine missing chunks -	 * and when to fast retransmit. -	 */ -	retval->tsn_missing_report = 0; -	retval->tsn_gap_acked = 0; -	retval->fast_retransmit = SCTP_CAN_FRTX; -	/* If this is a fragmented message, track all fragments -	 * of the message (for SEND_FAILED). -	 */ -	retval->msg = NULL; +	retval->fast_retransmit = SCTP_CAN_FRTX;  	/* Polish the bead hole.  */  	INIT_LIST_HEAD(&retval->transmitted_list); @@ -1433,8 +1422,8 @@ static void sctp_chunk_destroy(struct sctp_chunk *chunk)  	BUG_ON(!list_empty(&chunk->list));  	list_del_init(&chunk->transmitted_list); -	/* Free the chunk skb data and the SCTP_chunk stub itself. */ -	dev_kfree_skb(chunk->skb); +	consume_skb(chunk->skb); +	consume_skb(chunk->auth_chunk);  	SCTP_DBG_OBJCNT_DEC(chunk);  	kmem_cache_free(sctp_chunk_cachep, chunk); @@ -1489,8 +1478,8 @@ void *sctp_addto_chunk(struct sctp_chunk *chunk, int len, const void *data)  /* Append bytes to the end of a chunk. Returns NULL if there isn't sufficient   * space in the chunk   */ -void *sctp_addto_chunk_fixed(struct sctp_chunk *chunk, -			     int len, const void *data) +static void *sctp_addto_chunk_fixed(struct sctp_chunk *chunk, +				    int len, const void *data)  {  	if (skb_tailroom(chunk->skb) >= len)  		return sctp_addto_chunk(chunk, len, data); @@ -1793,7 +1782,7 @@ no_hmac:  	else  		kt = ktime_get(); -	if (!asoc && ktime_compare(bear_cookie->expiration, kt) < 0) { +	if (!asoc && ktime_before(bear_cookie->expiration, kt)) {  		/*  		 * Section 3.3.10.3 Stale Cookie Error (3)  		 * @@ -1981,13 +1970,13 @@ static int sctp_verify_ext_param(struct net *net, union sctp_params param)  	for (i = 0; i < num_ext; i++) {  		switch (param.ext->chunks[i]) { -		    case SCTP_CID_AUTH: -			    have_auth = 1; -			    break; -		    case SCTP_CID_ASCONF: -		    case SCTP_CID_ASCONF_ACK: -			    have_asconf = 1; -			    break; +		case SCTP_CID_AUTH: +			have_auth = 1; +			break; +		case SCTP_CID_ASCONF: +		case SCTP_CID_ASCONF_ACK: +			have_asconf = 1; +			break;  		}  	} @@ -2014,25 +2003,24 @@ static void sctp_process_ext_param(struct sctp_association *asoc,  	for (i = 0; i < num_ext; i++) {  		switch (param.ext->chunks[i]) { -		    case SCTP_CID_FWD_TSN: -			    if (net->sctp.prsctp_enable && -				!asoc->peer.prsctp_capable) +		case SCTP_CID_FWD_TSN: +			if (net->sctp.prsctp_enable && !asoc->peer.prsctp_capable)  				    asoc->peer.prsctp_capable = 1; -			    break; -		    case SCTP_CID_AUTH: -			    /* if the peer reports AUTH, assume that he -			     * supports AUTH. -			     */ -			    if (net->sctp.auth_enable) -				    asoc->peer.auth_capable = 1; -			    break; -		    case SCTP_CID_ASCONF: -		    case SCTP_CID_ASCONF_ACK: -			    if (net->sctp.addip_enable) -				    asoc->peer.asconf_capable = 1; -			    break; -		    default: -			    break; +			break; +		case SCTP_CID_AUTH: +			/* if the peer reports AUTH, assume that he +			 * supports AUTH. +			 */ +			if (asoc->ep->auth_enable) +				asoc->peer.auth_capable = 1; +			break; +		case SCTP_CID_ASCONF: +		case SCTP_CID_ASCONF_ACK: +			if (net->sctp.addip_enable) +				asoc->peer.asconf_capable = 1; +			break; +		default: +			break;  		}  	}  } @@ -2115,6 +2103,7 @@ static sctp_ierror_t sctp_process_unk_param(const struct sctp_association *asoc,   * 	SCTP_IERROR_NO_ERROR - continue with the chunk   */  static sctp_ierror_t sctp_verify_param(struct net *net, +					const struct sctp_endpoint *ep,  					const struct sctp_association *asoc,  					union sctp_params param,  					sctp_cid_t cid, @@ -2165,7 +2154,7 @@ static sctp_ierror_t sctp_verify_param(struct net *net,  		goto fallthrough;  	case SCTP_PARAM_RANDOM: -		if (!net->sctp.auth_enable) +		if (!ep->auth_enable)  			goto fallthrough;  		/* SCTP-AUTH: Secion 6.1 @@ -2182,7 +2171,7 @@ static sctp_ierror_t sctp_verify_param(struct net *net,  		break;  	case SCTP_PARAM_CHUNKS: -		if (!net->sctp.auth_enable) +		if (!ep->auth_enable)  			goto fallthrough;  		/* SCTP-AUTH: Section 3.2 @@ -2198,7 +2187,7 @@ static sctp_ierror_t sctp_verify_param(struct net *net,  		break;  	case SCTP_PARAM_HMAC_ALGO: -		if (!net->sctp.auth_enable) +		if (!ep->auth_enable)  			goto fallthrough;  		hmacs = (struct sctp_hmac_algo_param *)param.p; @@ -2233,10 +2222,9 @@ fallthrough:  }  /* Verify the INIT packet before we process it.  */ -int sctp_verify_init(struct net *net, const struct sctp_association *asoc, -		     sctp_cid_t cid, -		     sctp_init_chunk_t *peer_init, -		     struct sctp_chunk *chunk, +int sctp_verify_init(struct net *net, const struct sctp_endpoint *ep, +		     const struct sctp_association *asoc, sctp_cid_t cid, +		     sctp_init_chunk_t *peer_init, struct sctp_chunk *chunk,  		     struct sctp_chunk **errp)  {  	union sctp_params param; @@ -2265,7 +2253,7 @@ int sctp_verify_init(struct net *net, const struct sctp_association *asoc,  	 * VIOLATION error.  We build the ERROR chunk here and let the normal  	 * error handling code build and send the packet.  	 */ -	if (param.v != (void*)chunk->chunk_end) +	if (param.v != (void *)chunk->chunk_end)  		return sctp_process_inv_paramlength(asoc, param.p, chunk, errp);  	/* The only missing mandatory param possible today is @@ -2277,17 +2265,17 @@ int sctp_verify_init(struct net *net, const struct sctp_association *asoc,  	/* Verify all the variable length parameters */  	sctp_walk_params(param, peer_init, init_hdr.params) { - -		result = sctp_verify_param(net, asoc, param, cid, chunk, errp); +		result = sctp_verify_param(net, ep, asoc, param, cid, +					   chunk, errp);  		switch (result) { -		    case SCTP_IERROR_ABORT: -		    case SCTP_IERROR_NOMEM: -				return 0; -		    case SCTP_IERROR_ERROR: -				return 1; -		    case SCTP_IERROR_NO_ERROR: -		    default: -				break; +		case SCTP_IERROR_ABORT: +		case SCTP_IERROR_NOMEM: +			return 0; +		case SCTP_IERROR_ERROR: +			return 1; +		case SCTP_IERROR_NO_ERROR: +		default: +			break;  		}  	} /* for (loop through all parameters) */ @@ -2322,7 +2310,7 @@ int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk,  	 * added as the primary transport.  The source address seems to  	 * be a a better choice than any of the embedded addresses.  	 */ -	if(!sctp_assoc_add_peer(asoc, peer_addr, gfp, SCTP_ACTIVE)) +	if (!sctp_assoc_add_peer(asoc, peer_addr, gfp, SCTP_ACTIVE))  		goto nomem;  	if (sctp_cmp_addr_exact(sctp_source(chunk), peer_addr)) @@ -2510,6 +2498,7 @@ static int sctp_process_param(struct sctp_association *asoc,  	struct sctp_af *af;  	union sctp_addr_param *addr_param;  	struct sctp_transport *t; +	struct sctp_endpoint *ep = asoc->ep;  	/* We maintain all INIT parameters in network byte order all the  	 * time.  This allows us to not worry about whether the parameters @@ -2649,7 +2638,7 @@ do_addr_param:  		goto fall_through;  	case SCTP_PARAM_RANDOM: -		if (!net->sctp.auth_enable) +		if (!ep->auth_enable)  			goto fall_through;  		/* Save peer's random parameter */ @@ -2662,7 +2651,7 @@ do_addr_param:  		break;  	case SCTP_PARAM_HMAC_ALGO: -		if (!net->sctp.auth_enable) +		if (!ep->auth_enable)  			goto fall_through;  		/* Save peer's HMAC list */ @@ -2678,7 +2667,7 @@ do_addr_param:  		break;  	case SCTP_PARAM_CHUNKS: -		if (!net->sctp.auth_enable) +		if (!ep->auth_enable)  			goto fall_through;  		asoc->peer.peer_chunks = kmemdup(param.p, @@ -3348,7 +3337,7 @@ static __be16 sctp_get_asconf_response(struct sctp_chunk *asconf_ack,  	while (asconf_ack_len > 0) {  		if (asconf_ack_param->crr_id == asconf_param->crr_id) { -			switch(asconf_ack_param->param_hdr.type) { +			switch (asconf_ack_param->param_hdr.type) {  			case SCTP_PARAM_SUCCESS_REPORT:  				return SCTP_ERROR_NO_ERROR;  			case SCTP_PARAM_ERR_CAUSE:  | 
