net/sctp/stream.c

Source file repositories/reference/linux-study-clean/net/sctp/stream.c

File Facts

System
Linux kernel
Corpus path
net/sctp/stream.c
Extension
.c
Size
27388 bytes
Lines
1092
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: implementation source
Status
source implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

if (out) {
			for (i = 0; i < str_nums; i++)
				if (str_list[i] >= stream->outcnt)
					goto out;

			param_len = str_nums * sizeof(__u16) +
				    sizeof(struct sctp_strreset_outreq);
		}

		if (in) {
			for (i = 0; i < str_nums; i++)
				if (str_list[i] >= stream->incnt)
					goto out;

			param_len += str_nums * sizeof(__u16) +
				     sizeof(struct sctp_strreset_inreq);
		}

		if (param_len > SCTP_MAX_CHUNK_LEN -
				sizeof(struct sctp_reconf_chunk))
			goto out;
	}

	nstr_list = kcalloc(str_nums, sizeof(__be16), GFP_KERNEL);
	if (!nstr_list) {
		retval = -ENOMEM;
		goto out;
	}

	for (i = 0; i < str_nums; i++)
		nstr_list[i] = htons(str_list[i]);

	if (out && !sctp_stream_outq_is_empty(stream, str_nums, nstr_list)) {
		kfree(nstr_list);
		retval = -EAGAIN;
		goto out;
	}

	chunk = sctp_make_strreset_req(asoc, str_nums, nstr_list, out, in);

	kfree(nstr_list);

	if (!chunk) {
		retval = -ENOMEM;
		goto out;
	}

	if (out) {
		if (str_nums)
			for (i = 0; i < str_nums; i++)
				SCTP_SO(stream, str_list[i])->state =
						       SCTP_STREAM_CLOSED;
		else
			for (i = 0; i < stream->outcnt; i++)
				SCTP_SO(stream, i)->state = SCTP_STREAM_CLOSED;
	}

	asoc->strreset_chunk = chunk;
	sctp_chunk_hold(asoc->strreset_chunk);

	retval = sctp_send_reconf(asoc, chunk);
	if (retval) {
		sctp_chunk_put(asoc->strreset_chunk);
		asoc->strreset_chunk = NULL;
		if (!out)
			goto out;

		if (str_nums)
			for (i = 0; i < str_nums; i++)
				SCTP_SO(stream, str_list[i])->state =
						       SCTP_STREAM_OPEN;
		else
			for (i = 0; i < stream->outcnt; i++)
				SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;

		goto out;
	}

	asoc->strreset_outstanding = out + in;

out:
	return retval;
}

int sctp_send_reset_assoc(struct sctp_association *asoc)
{
	struct sctp_stream *stream = &asoc->stream;
	struct sctp_chunk *chunk = NULL;
	int retval;
	__u16 i;

Annotation

Implementation Notes