[DCCP]: Introduce DCCP_SOCKOPT_PACKET_SIZE

So that applications can set dccp_sock->dccps_pkt_size, that in turn
is used in the CCID3 half connection init routines to set
ccid3hc[tr]x_s and use it in its rate calculations.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Arnaldo Carvalho de Melo and committed by
David S. Miller
a84ffe43 0ac4f893

+59 -12
+5 -2
include/linux/dccp.h
··· 186 DCCPF_MAX_CCID_SPECIFIC = 255, 187 }; 188 189 #ifdef __KERNEL__ 190 191 #include <linux/in.h> ··· 399 * @dccps_timestamp_echo - latest timestamp received on a TIMESTAMP option 400 * @dccps_ext_header_len - network protocol overhead (IP/IPv6 options) 401 * @dccps_pmtu_cookie - Last pmtu seen by socket 402 - * @dccps_avg_packet_size - FIXME: has to be set by the app thru some setsockopt or ioctl, CCID3 uses it 403 * @dccps_role - Role of this sock, one of %dccp_role 404 * @dccps_ndp_count - number of Non Data Packets since last data packet 405 * @dccps_hc_rx_ackpkts - receiver half connection acked packets ··· 420 unsigned long dccps_service; 421 struct timeval dccps_timestamp_time; 422 __u32 dccps_timestamp_echo; 423 - __u32 dccps_avg_packet_size; 424 unsigned long dccps_ndp_count; 425 __u16 dccps_ext_header_len; 426 __u32 dccps_pmtu_cookie;
··· 186 DCCPF_MAX_CCID_SPECIFIC = 255, 187 }; 188 189 + /* DCCP socket options */ 190 + #define DCCP_SOCKOPT_PACKET_SIZE 1 191 + 192 #ifdef __KERNEL__ 193 194 #include <linux/in.h> ··· 396 * @dccps_timestamp_echo - latest timestamp received on a TIMESTAMP option 397 * @dccps_ext_header_len - network protocol overhead (IP/IPv6 options) 398 * @dccps_pmtu_cookie - Last pmtu seen by socket 399 + * @dccps_packet_size - Set thru setsockopt 400 * @dccps_role - Role of this sock, one of %dccp_role 401 * @dccps_ndp_count - number of Non Data Packets since last data packet 402 * @dccps_hc_rx_ackpkts - receiver half connection acked packets ··· 417 unsigned long dccps_service; 418 struct timeval dccps_timestamp_time; 419 __u32 dccps_timestamp_echo; 420 + __u32 dccps_packet_size; 421 unsigned long dccps_ndp_count; 422 __u16 dccps_ext_header_len; 423 __u32 dccps_pmtu_cookie;
+6 -6
net/dccp/ccids/ccid3.c
··· 672 673 memset(hctx, 0, sizeof(*hctx)); 674 675 - if (dp->dccps_avg_packet_size >= TFRC_MIN_PACKET_SIZE && 676 - dp->dccps_avg_packet_size <= TFRC_MAX_PACKET_SIZE) 677 - hctx->ccid3hctx_s = (u16)dp->dccps_avg_packet_size; 678 else 679 hctx->ccid3hctx_s = TFRC_STD_PACKET_SIZE; 680 ··· 1058 1059 memset(hcrx, 0, sizeof(*hcrx)); 1060 1061 - if (dp->dccps_avg_packet_size >= TFRC_MIN_PACKET_SIZE && 1062 - dp->dccps_avg_packet_size <= TFRC_MAX_PACKET_SIZE) 1063 - hcrx->ccid3hcrx_s = (u16)dp->dccps_avg_packet_size; 1064 else 1065 hcrx->ccid3hcrx_s = TFRC_STD_PACKET_SIZE; 1066
··· 672 673 memset(hctx, 0, sizeof(*hctx)); 674 675 + if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE && 676 + dp->dccps_packet_size <= TFRC_MAX_PACKET_SIZE) 677 + hctx->ccid3hctx_s = dp->dccps_packet_size; 678 else 679 hctx->ccid3hctx_s = TFRC_STD_PACKET_SIZE; 680 ··· 1058 1059 memset(hcrx, 0, sizeof(*hcrx)); 1060 1061 + if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE && 1062 + dp->dccps_packet_size <= TFRC_MAX_PACKET_SIZE) 1063 + hcrx->ccid3hcrx_s = dp->dccps_packet_size; 1064 else 1065 hcrx->ccid3hcrx_s = TFRC_STD_PACKET_SIZE; 1066
+48 -4
net/dccp/proto.c
··· 205 int dccp_setsockopt(struct sock *sk, int level, int optname, 206 char __user *optval, int optlen) 207 { 208 - dccp_pr_debug("entry\n"); 209 210 if (level != SOL_DCCP) 211 return ip_setsockopt(sk, level, optname, optval, optlen); 212 213 - return -EOPNOTSUPP; 214 } 215 216 int dccp_getsockopt(struct sock *sk, int level, int optname, 217 char __user *optval, int __user *optlen) 218 { 219 - dccp_pr_debug("entry\n"); 220 221 if (level != SOL_DCCP) 222 return ip_getsockopt(sk, level, optname, optval, optlen); 223 224 - return -EOPNOTSUPP; 225 } 226 227 int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
··· 205 int dccp_setsockopt(struct sock *sk, int level, int optname, 206 char __user *optval, int optlen) 207 { 208 + struct dccp_sock *dp; 209 + int err; 210 + int val; 211 212 if (level != SOL_DCCP) 213 return ip_setsockopt(sk, level, optname, optval, optlen); 214 215 + if (optlen < sizeof(int)) 216 + return -EINVAL; 217 + 218 + if (get_user(val, (int __user *)optval)) 219 + return -EFAULT; 220 + 221 + lock_sock(sk); 222 + 223 + dp = dccp_sk(sk); 224 + err = 0; 225 + 226 + switch (optname) { 227 + case DCCP_SOCKOPT_PACKET_SIZE: 228 + dp->dccps_packet_size = val; 229 + break; 230 + default: 231 + err = -ENOPROTOOPT; 232 + break; 233 + } 234 + 235 + release_sock(sk); 236 + return err; 237 } 238 239 int dccp_getsockopt(struct sock *sk, int level, int optname, 240 char __user *optval, int __user *optlen) 241 { 242 + struct dccp_sock *dp; 243 + int val, len; 244 245 if (level != SOL_DCCP) 246 return ip_getsockopt(sk, level, optname, optval, optlen); 247 248 + if (get_user(len, optlen)) 249 + return -EFAULT; 250 + 251 + len = min_t(unsigned int, len, sizeof(int)); 252 + if (len < 0) 253 + return -EINVAL; 254 + 255 + dp = dccp_sk(sk); 256 + 257 + switch (optname) { 258 + case DCCP_SOCKOPT_PACKET_SIZE: 259 + val = dp->dccps_packet_size; 260 + break; 261 + default: 262 + return -ENOPROTOOPT; 263 + } 264 + 265 + if (put_user(len, optlen) || copy_to_user(optval, &val, len)) 266 + return -EFAULT; 267 + 268 + return 0; 269 } 270 271 int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,