Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 122862
b: refs/heads/master
c: e89c209
h: refs/heads/master
v: v3
  • Loading branch information
Wei Yongjun authored and David S. Miller committed Dec 26, 2008
1 parent d19af58 commit b514487
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 24 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 161c8d2f50109b44b664eaf23831ea1587979a61
refs/heads/master: e89c2095815d82eaa9fb85eff42f8b65b67a59cf
130 changes: 107 additions & 23 deletions trunk/net/sctp/socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -2778,32 +2778,77 @@ static int sctp_setsockopt_mappedv4(struct sock *sk, char __user *optval, int op
}

/*
* 7.1.17 Set the maximum fragrmentation size (SCTP_MAXSEG)
*
* This socket option specifies the maximum size to put in any outgoing
* SCTP chunk. If a message is larger than this size it will be
* 8.1.16. Get or Set the Maximum Fragmentation Size (SCTP_MAXSEG)
* This option will get or set the maximum size to put in any outgoing
* SCTP DATA chunk. If a message is larger than this size it will be
* fragmented by SCTP into the specified size. Note that the underlying
* SCTP implementation may fragment into smaller sized chunks when the
* PMTU of the underlying association is smaller than the value set by
* the user.
* the user. The default value for this option is '0' which indicates
* the user is NOT limiting fragmentation and only the PMTU will effect
* SCTP's choice of DATA chunk size. Note also that values set larger
* than the maximum size of an IP datagram will effectively let SCTP
* control fragmentation (i.e. the same as setting this option to 0).
*
* The following structure is used to access and modify this parameter:
*
* struct sctp_assoc_value {
* sctp_assoc_t assoc_id;
* uint32_t assoc_value;
* };
*
* assoc_id: This parameter is ignored for one-to-one style sockets.
* For one-to-many style sockets this parameter indicates which
* association the user is performing an action upon. Note that if
* this field's value is zero then the endpoints default value is
* changed (effecting future associations only).
* assoc_value: This parameter specifies the maximum size in bytes.
*/
static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, int optlen)
{
struct sctp_assoc_value params;
struct sctp_association *asoc;
struct sctp_sock *sp = sctp_sk(sk);
int val;

if (optlen < sizeof(int))
if (optlen == sizeof(int)) {
printk(KERN_WARNING
"SCTP: Use of int in maxseg socket option deprecated\n");
printk(KERN_WARNING
"SCTP: Use struct sctp_assoc_value instead\n");
if (copy_from_user(&val, optval, optlen))
return -EFAULT;
params.assoc_id = 0;
} else if (optlen == sizeof(struct sctp_assoc_value)) {
if (copy_from_user(&params, optval, optlen))
return -EFAULT;
val = params.assoc_value;
} else
return -EINVAL;
if (get_user(val, (int __user *)optval))
return -EFAULT;

if ((val != 0) && ((val < 8) || (val > SCTP_MAX_CHUNK_LEN)))
return -EINVAL;
sp->user_frag = val;

/* Update the frag_point of the existing associations. */
list_for_each_entry(asoc, &(sp->ep->asocs), asocs) {
asoc->frag_point = sctp_frag_point(sp, asoc->pathmtu);
asoc = sctp_id2assoc(sk, params.assoc_id);
if (!asoc && params.assoc_id && sctp_style(sk, UDP))
return -EINVAL;

if (asoc) {
if (val == 0) {
val = asoc->pathmtu;
val -= sp->pf->af->net_header_len;
val -= sizeof(struct sctphdr) +
sizeof(struct sctp_data_chunk);
}

asoc->frag_point = val;
} else {
sp->user_frag = val;

/* Update the frag_point of the existing associations. */
list_for_each_entry(asoc, &(sp->ep->asocs), asocs) {
asoc->frag_point = sctp_frag_point(sp, asoc->pathmtu);
}
}

return 0;
Expand Down Expand Up @@ -5100,30 +5145,69 @@ static int sctp_getsockopt_context(struct sock *sk, int len,
}

/*
* 7.1.17 Set the maximum fragrmentation size (SCTP_MAXSEG)
*
* This socket option specifies the maximum size to put in any outgoing
* SCTP chunk. If a message is larger than this size it will be
* 8.1.16. Get or Set the Maximum Fragmentation Size (SCTP_MAXSEG)
* This option will get or set the maximum size to put in any outgoing
* SCTP DATA chunk. If a message is larger than this size it will be
* fragmented by SCTP into the specified size. Note that the underlying
* SCTP implementation may fragment into smaller sized chunks when the
* PMTU of the underlying association is smaller than the value set by
* the user.
* the user. The default value for this option is '0' which indicates
* the user is NOT limiting fragmentation and only the PMTU will effect
* SCTP's choice of DATA chunk size. Note also that values set larger
* than the maximum size of an IP datagram will effectively let SCTP
* control fragmentation (i.e. the same as setting this option to 0).
*
* The following structure is used to access and modify this parameter:
*
* struct sctp_assoc_value {
* sctp_assoc_t assoc_id;
* uint32_t assoc_value;
* };
*
* assoc_id: This parameter is ignored for one-to-one style sockets.
* For one-to-many style sockets this parameter indicates which
* association the user is performing an action upon. Note that if
* this field's value is zero then the endpoints default value is
* changed (effecting future associations only).
* assoc_value: This parameter specifies the maximum size in bytes.
*/
static int sctp_getsockopt_maxseg(struct sock *sk, int len,
char __user *optval, int __user *optlen)
{
int val;
struct sctp_assoc_value params;
struct sctp_association *asoc;

if (len < sizeof(int))
if (len == sizeof(int)) {
printk(KERN_WARNING
"SCTP: Use of int in maxseg socket option deprecated\n");
printk(KERN_WARNING
"SCTP: Use struct sctp_assoc_value instead\n");
params.assoc_id = 0;
} else if (len >= sizeof(struct sctp_assoc_value)) {
len = sizeof(struct sctp_assoc_value);
if (copy_from_user(&params, optval, sizeof(params)))
return -EFAULT;
} else
return -EINVAL;

len = sizeof(int);
asoc = sctp_id2assoc(sk, params.assoc_id);
if (!asoc && params.assoc_id && sctp_style(sk, UDP))
return -EINVAL;

if (asoc)
params.assoc_value = asoc->frag_point;
else
params.assoc_value = sctp_sk(sk)->user_frag;

val = sctp_sk(sk)->user_frag;
if (put_user(len, optlen))
return -EFAULT;
if (copy_to_user(optval, &val, len))
return -EFAULT;
if (len == sizeof(int)) {
if (copy_to_user(optval, &params.assoc_value, len))
return -EFAULT;
} else {
if (copy_to_user(optval, &params, len))
return -EFAULT;
}

return 0;
}
Expand Down

0 comments on commit b514487

Please sign in to comment.