static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, unsigned int optlen)
{
	struct sctp_sock *sp = sctp_sk(sk);
	struct sctp_assoc_value params;
	struct sctp_association *asoc;
	int val;

	if (optlen == sizeof(int)) {
		pr_warn_ratelimited(DEPRECATED
				    "%s (pid %d) "
				    "Use of int in maxseg socket option.\n"
				    "Use struct sctp_assoc_value instead\n",
				    current->comm, task_pid_nr(current));
		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 (val) {
		int min_len, max_len;

		min_len = SCTP_DEFAULT_MINSEGMENT - sp->pf->af->net_header_len;
		min_len -= sizeof(struct sctphdr) +
			   sizeof(struct sctp_data_chunk);

		max_len = SCTP_MAX_CHUNK_LEN - sizeof(struct sctp_data_chunk);

		if (val < min_len || val > max_len)
			return -EINVAL;
	}

	asoc = sctp_id2assoc(sk, params.assoc_id);
	if (asoc) {
		if (val == 0) {
			val = asoc->pathmtu - sp->pf->af->net_header_len;
			val -= sizeof(struct sctphdr) +
			       sizeof(struct sctp_data_chunk);
		}
		asoc->user_frag = val;
		asoc->frag_point = sctp_frag_point(asoc, asoc->pathmtu);
	} else {
		if (params.assoc_id && sctp_style(sk, UDP))
			return -EINVAL;
		sp->user_frag = val;
	}

	return 0;
}
static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, unsigned int optlen)
{
	struct sctp_sock *sp = sctp_sk(sk);
	struct sctp_assoc_value params;
	struct sctp_association *asoc;
	int val;

	if (optlen == sizeof(int)) {
		pr_warn_ratelimited(DEPRECATED
				    "%s (pid %d) "
				    "Use of int in maxseg socket option.\n"
				    "Use struct sctp_assoc_value instead\n",
				    current->comm, task_pid_nr(current));
		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 (val) {
		int min_len, max_len;

		min_len = SCTP_DEFAULT_MINSEGMENT - sp->pf->af->net_header_len;
		min_len -= sizeof(struct sctphdr) +
			   sizeof(struct sctp_data_chunk);

		max_len = SCTP_MAX_CHUNK_LEN - sizeof(struct sctp_data_chunk);

		if (val < min_len || val > max_len)
			return -EINVAL;
	}

	asoc = sctp_id2assoc(sk, params.assoc_id);
	if (asoc) {
		if (val == 0) {
			val = asoc->pathmtu - sp->pf->af->net_header_len;
			val -= sizeof(struct sctphdr) +
			       sizeof(struct sctp_data_chunk);
		}
		asoc->user_frag = val;
		asoc->frag_point = sctp_frag_point(asoc, asoc->pathmtu);
	} else {
		if (params.assoc_id && sctp_style(sk, UDP))
			return -EINVAL;
		sp->user_frag = val;
	}

	return 0;
}