Commit a84ffe43 authored by Arnaldo Carvalho de Melo's avatar Arnaldo Carvalho de Melo Committed by David S. Miller

[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: default avatarArnaldo Carvalho de Melo <acme@mandriva.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0ac4f893
...@@ -186,6 +186,9 @@ enum { ...@@ -186,6 +186,9 @@ enum {
DCCPF_MAX_CCID_SPECIFIC = 255, DCCPF_MAX_CCID_SPECIFIC = 255,
}; };
/* DCCP socket options */
#define DCCP_SOCKOPT_PACKET_SIZE 1
#ifdef __KERNEL__ #ifdef __KERNEL__
#include <linux/in.h> #include <linux/in.h>
...@@ -396,7 +399,7 @@ enum dccp_role { ...@@ -396,7 +399,7 @@ enum dccp_role {
* @dccps_timestamp_echo - latest timestamp received on a TIMESTAMP option * @dccps_timestamp_echo - latest timestamp received on a TIMESTAMP option
* @dccps_ext_header_len - network protocol overhead (IP/IPv6 options) * @dccps_ext_header_len - network protocol overhead (IP/IPv6 options)
* @dccps_pmtu_cookie - Last pmtu seen by socket * @dccps_pmtu_cookie - Last pmtu seen by socket
* @dccps_avg_packet_size - FIXME: has to be set by the app thru some setsockopt or ioctl, CCID3 uses it * @dccps_packet_size - Set thru setsockopt
* @dccps_role - Role of this sock, one of %dccp_role * @dccps_role - Role of this sock, one of %dccp_role
* @dccps_ndp_count - number of Non Data Packets since last data packet * @dccps_ndp_count - number of Non Data Packets since last data packet
* @dccps_hc_rx_ackpkts - receiver half connection acked packets * @dccps_hc_rx_ackpkts - receiver half connection acked packets
...@@ -417,7 +420,7 @@ struct dccp_sock { ...@@ -417,7 +420,7 @@ struct dccp_sock {
unsigned long dccps_service; unsigned long dccps_service;
struct timeval dccps_timestamp_time; struct timeval dccps_timestamp_time;
__u32 dccps_timestamp_echo; __u32 dccps_timestamp_echo;
__u32 dccps_avg_packet_size; __u32 dccps_packet_size;
unsigned long dccps_ndp_count; unsigned long dccps_ndp_count;
__u16 dccps_ext_header_len; __u16 dccps_ext_header_len;
__u32 dccps_pmtu_cookie; __u32 dccps_pmtu_cookie;
......
...@@ -672,9 +672,9 @@ static int ccid3_hc_tx_init(struct sock *sk) ...@@ -672,9 +672,9 @@ static int ccid3_hc_tx_init(struct sock *sk)
memset(hctx, 0, sizeof(*hctx)); memset(hctx, 0, sizeof(*hctx));
if (dp->dccps_avg_packet_size >= TFRC_MIN_PACKET_SIZE && if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE &&
dp->dccps_avg_packet_size <= TFRC_MAX_PACKET_SIZE) dp->dccps_packet_size <= TFRC_MAX_PACKET_SIZE)
hctx->ccid3hctx_s = (u16)dp->dccps_avg_packet_size; hctx->ccid3hctx_s = dp->dccps_packet_size;
else else
hctx->ccid3hctx_s = TFRC_STD_PACKET_SIZE; hctx->ccid3hctx_s = TFRC_STD_PACKET_SIZE;
...@@ -1058,9 +1058,9 @@ static int ccid3_hc_rx_init(struct sock *sk) ...@@ -1058,9 +1058,9 @@ static int ccid3_hc_rx_init(struct sock *sk)
memset(hcrx, 0, sizeof(*hcrx)); memset(hcrx, 0, sizeof(*hcrx));
if (dp->dccps_avg_packet_size >= TFRC_MIN_PACKET_SIZE && if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE &&
dp->dccps_avg_packet_size <= TFRC_MAX_PACKET_SIZE) dp->dccps_packet_size <= TFRC_MAX_PACKET_SIZE)
hcrx->ccid3hcrx_s = (u16)dp->dccps_avg_packet_size; hcrx->ccid3hcrx_s = dp->dccps_packet_size;
else else
hcrx->ccid3hcrx_s = TFRC_STD_PACKET_SIZE; hcrx->ccid3hcrx_s = TFRC_STD_PACKET_SIZE;
......
...@@ -205,23 +205,67 @@ int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg) ...@@ -205,23 +205,67 @@ int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg)
int dccp_setsockopt(struct sock *sk, int level, int optname, int dccp_setsockopt(struct sock *sk, int level, int optname,
char __user *optval, int optlen) char __user *optval, int optlen)
{ {
dccp_pr_debug("entry\n"); struct dccp_sock *dp;
int err;
int val;
if (level != SOL_DCCP) if (level != SOL_DCCP)
return ip_setsockopt(sk, level, optname, optval, optlen); return ip_setsockopt(sk, level, optname, optval, optlen);
return -EOPNOTSUPP; if (optlen < sizeof(int))
return -EINVAL;
if (get_user(val, (int __user *)optval))
return -EFAULT;
lock_sock(sk);
dp = dccp_sk(sk);
err = 0;
switch (optname) {
case DCCP_SOCKOPT_PACKET_SIZE:
dp->dccps_packet_size = val;
break;
default:
err = -ENOPROTOOPT;
break;
}
release_sock(sk);
return err;
} }
int dccp_getsockopt(struct sock *sk, int level, int optname, int dccp_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen) char __user *optval, int __user *optlen)
{ {
dccp_pr_debug("entry\n"); struct dccp_sock *dp;
int val, len;
if (level != SOL_DCCP) if (level != SOL_DCCP)
return ip_getsockopt(sk, level, optname, optval, optlen); return ip_getsockopt(sk, level, optname, optval, optlen);
return -EOPNOTSUPP; if (get_user(len, optlen))
return -EFAULT;
len = min_t(unsigned int, len, sizeof(int));
if (len < 0)
return -EINVAL;
dp = dccp_sk(sk);
switch (optname) {
case DCCP_SOCKOPT_PACKET_SIZE:
val = dp->dccps_packet_size;
break;
default:
return -ENOPROTOOPT;
}
if (put_user(len, optlen) || copy_to_user(optval, &val, len))
return -EFAULT;
return 0;
} }
int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment