[SCTP]: Implement SCTP_MAX_BURST socket option.
Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
				
					committed by
					
						 David S. Miller
						David S. Miller
					
				
			
			
				
	
			
			
			
						parent
						
							a5a35e7675
						
					
				
				
					commit
					703315712c
				
			| @@ -283,7 +283,7 @@ enum { SCTP_MAX_GABS = 16 }; | ||||
| #define SCTP_RTO_BETA           2   /* 1/4 when converted to right shifts. */ | ||||
|  | ||||
| /* Maximum number of new data packets that can be sent in a burst.  */ | ||||
| #define SCTP_MAX_BURST		4 | ||||
| #define SCTP_DEFAULT_MAX_BURST		4 | ||||
|  | ||||
| #define SCTP_CLOCK_GRANULARITY	1	/* 1 jiffy */ | ||||
|  | ||||
|   | ||||
| @@ -276,6 +276,7 @@ struct sctp_sock { | ||||
| 	__u32 default_context; | ||||
| 	__u32 default_timetolive; | ||||
| 	__u32 default_rcv_context; | ||||
| 	int max_burst; | ||||
|  | ||||
| 	/* Heartbeat interval: The endpoint sends out a Heartbeat chunk to | ||||
| 	 * the destination address every heartbeat interval. This value | ||||
|   | ||||
| @@ -101,6 +101,8 @@ enum sctp_optname { | ||||
| #define SCTP_FRAGMENT_INTERLEAVE SCTP_FRAGMENT_INTERLEAVE | ||||
| 	SCTP_PARTIAL_DELIVERY_POINT,	/* Set/Get partial delivery point */ | ||||
| #define SCTP_PARTIAL_DELIVERY_POINT SCTP_PARTIAL_DELIVERY_POINT | ||||
| 	SCTP_MAX_BURST,		/* Set/Get max burst */ | ||||
| #define SCTP_MAX_BURST SCTP_MAX_BURST | ||||
|  | ||||
| 	/* Internal Socket Options. Some of the sctp library functions are  | ||||
| 	 * implemented using these socket options. | ||||
|   | ||||
| @@ -143,7 +143,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a | ||||
| 	/* Initialize the maximum mumber of new data packets that can be sent | ||||
| 	 * in a burst. | ||||
| 	 */ | ||||
| 	asoc->max_burst = sctp_max_burst; | ||||
| 	asoc->max_burst = sp->max_burst; | ||||
|  | ||||
| 	/* initialize association timers */ | ||||
| 	asoc->timeouts[SCTP_EVENT_TIMEOUT_NONE] = 0; | ||||
|   | ||||
| @@ -1042,7 +1042,7 @@ SCTP_STATIC __init int sctp_init(void) | ||||
| 	sctp_cookie_preserve_enable 	= 1; | ||||
|  | ||||
| 	/* Max.Burst		    - 4 */ | ||||
| 	sctp_max_burst 			= SCTP_MAX_BURST; | ||||
| 	sctp_max_burst 			= SCTP_DEFAULT_MAX_BURST; | ||||
|  | ||||
| 	/* Association.Max.Retrans  - 10 attempts | ||||
| 	 * Path.Max.Retrans         - 5  attempts (per destination address) | ||||
|   | ||||
| @@ -2892,6 +2892,36 @@ static int sctp_setsockopt_partial_delivery_point(struct sock *sk, | ||||
| 	return 0; /* is this the right error code? */ | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * 7.1.28.  Set or Get the maximum burst (SCTP_MAX_BURST) | ||||
|  * | ||||
|  * This option will allow a user to change the maximum burst of packets | ||||
|  * that can be emitted by this association.  Note that the default value | ||||
|  * is 4, and some implementations may restrict this setting so that it | ||||
|  * can only be lowered. | ||||
|  * | ||||
|  * NOTE: This text doesn't seem right.  Do this on a socket basis with | ||||
|  * future associations inheriting the socket value. | ||||
|  */ | ||||
| static int sctp_setsockopt_maxburst(struct sock *sk, | ||||
| 				    char __user *optval, | ||||
| 				    int optlen) | ||||
| { | ||||
| 	int val; | ||||
|  | ||||
| 	if (optlen != sizeof(int)) | ||||
| 		return -EINVAL; | ||||
| 	if (get_user(val, (int __user *)optval)) | ||||
| 		return -EFAULT; | ||||
|  | ||||
| 	if (val < 0) | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	sctp_sk(sk)->max_burst = val; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* API 6.2 setsockopt(), getsockopt() | ||||
|  * | ||||
|  * Applications use setsockopt() and getsockopt() to set or retrieve | ||||
| @@ -3012,6 +3042,9 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname, | ||||
| 	case SCTP_FRAGMENT_INTERLEAVE: | ||||
| 		retval = sctp_setsockopt_fragment_interleave(sk, optval, optlen); | ||||
| 		break; | ||||
| 	case SCTP_MAX_BURST: | ||||
| 		retval = sctp_setsockopt_maxburst(sk, optval, optlen); | ||||
| 		break; | ||||
| 	default: | ||||
| 		retval = -ENOPROTOOPT; | ||||
| 		break; | ||||
| @@ -3171,6 +3204,7 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk) | ||||
| 	sp->default_timetolive = 0; | ||||
|  | ||||
| 	sp->default_rcv_context = 0; | ||||
| 	sp->max_burst = sctp_max_burst; | ||||
|  | ||||
| 	/* Initialize default setup parameters. These parameters | ||||
| 	 * can be modified with the SCTP_INITMSG socket option or | ||||
| @@ -4689,6 +4723,30 @@ static int sctp_getsockopt_partial_delivery_point(struct sock *sk, int len, | ||||
| 	return -ENOTSUPP; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * 7.1.28.  Set or Get the maximum burst (SCTP_MAX_BURST) | ||||
|  * (chapter and verse is quoted at sctp_setsockopt_maxburst()) | ||||
|  */ | ||||
| static int sctp_getsockopt_maxburst(struct sock *sk, int len, | ||||
| 				    char __user *optval, | ||||
| 				    int __user *optlen) | ||||
| { | ||||
|         int val; | ||||
|  | ||||
| 	if (len < sizeof(int)) | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	len = sizeof(int); | ||||
|  | ||||
| 	val = sctp_sk(sk)->max_burst; | ||||
| 	if (put_user(len, optlen)) | ||||
| 		return -EFAULT; | ||||
| 	if (copy_to_user(optval, &val, len)) | ||||
| 		return -EFAULT; | ||||
|  | ||||
| 	return -ENOTSUPP; | ||||
| } | ||||
|  | ||||
| SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname, | ||||
| 				char __user *optval, int __user *optlen) | ||||
| { | ||||
| @@ -4809,6 +4867,9 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname, | ||||
| 		retval = sctp_getsockopt_partial_delivery_point(sk, len, optval, | ||||
| 								optlen); | ||||
| 		break; | ||||
| 	case SCTP_MAX_BURST: | ||||
| 		retval = sctp_getsockopt_maxburst(sk, len, optval, optlen); | ||||
| 		break; | ||||
| 	default: | ||||
| 		retval = -ENOPROTOOPT; | ||||
| 		break; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user