tools/testing/selftests/net/tcp_ao/lib/repair.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/net/tcp_ao/lib/repair.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/net/tcp_ao/lib/repair.c
Extension
.c
Size
6791 bytes
Lines
255
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

if (ret <= 0) {
			if (chunk > 1024) {
				chunk >>= 1;
				continue;
			}
			test_error("send()");
		}
		off += ret;
		len -= ret;
	} while (len > 0);
}

void __test_sock_restore(int sk, const char *device,
			 struct tcp_sock_state *state,
			 void *saddr, void *daddr, size_t addr_size)
{
	struct tcp_repair_opt opts[4];
	unsigned int opt_nr = 0;
	long flags;

	if (bind(sk, saddr, addr_size))
		test_error("bind()");

	flags = fcntl(sk, F_GETFL);
	if ((flags < 0) || (fcntl(sk, F_SETFL, flags | O_NONBLOCK) < 0))
		test_error("fcntl()");

	test_sock_restore_seq(sk, TCP_RECV_QUEUE, state->in.seq - state->inq_len);
	test_sock_restore_seq(sk, TCP_SEND_QUEUE, state->out.seq - state->outq_len);

	if (device != NULL && setsockopt(sk, SOL_SOCKET, SO_BINDTODEVICE,
					 device, strlen(device) + 1))
		test_error("setsockopt(SO_BINDTODEVICE, %s)", device);

	if (connect(sk, daddr, addr_size))
		test_error("connect()");

	if (state->info.tcpi_options & TCPI_OPT_SACK) {
		opts[opt_nr].opt_code = TCPOPT_SACK_PERMITTED;
		opts[opt_nr].opt_val = 0;
		opt_nr++;
	}
	if (state->info.tcpi_options & TCPI_OPT_WSCALE) {
		opts[opt_nr].opt_code = TCPOPT_WINDOW;
		opts[opt_nr].opt_val = state->info.tcpi_snd_wscale +
				(state->info.tcpi_rcv_wscale << 16);
		opt_nr++;
	}
	if (state->info.tcpi_options & TCPI_OPT_TIMESTAMPS) {
		opts[opt_nr].opt_code = TCPOPT_TIMESTAMP;
		opts[opt_nr].opt_val = 0;
		opt_nr++;
	}
	opts[opt_nr].opt_code = TCPOPT_MAXSEG;
	opts[opt_nr].opt_val = state->mss;
	opt_nr++;

	if (setsockopt(sk, SOL_TCP, TCP_REPAIR_OPTIONS, opts, opt_nr * sizeof(opts[0])))
		test_error("setsockopt(TCP_REPAIR_OPTIONS)");

	if (state->info.tcpi_options & TCPI_OPT_TIMESTAMPS) {
		if (setsockopt(sk, SOL_TCP, TCP_TIMESTAMP,
			       &state->timestamp, opt_nr * sizeof(opts[0])))
			test_error("setsockopt(TCP_TIMESTAMP)");
	}
	test_sock_restore_queue(sk, TCP_RECV_QUEUE, state->in.buf, state->inq_len);
	test_sock_restore_queue(sk, TCP_SEND_QUEUE, state->out.buf, state->outq_len);
	if (setsockopt(sk, SOL_TCP, TCP_REPAIR_WINDOW, &state->trw, sizeof(state->trw)))
		test_error("setsockopt(TCP_REPAIR_WINDOW)");
}

void test_ao_restore(int sk, struct tcp_ao_repair *state)
{
	if (setsockopt(sk, SOL_TCP, TCP_AO_REPAIR, state, sizeof(*state)))
		test_error("setsockopt(TCP_AO_REPAIR)");
}

void test_sock_state_free(struct tcp_sock_state *state)
{
	free(state->out.buf);
	free(state->in.buf);
}

void test_enable_repair(int sk)
{
	int val = TCP_REPAIR_ON;

	if (setsockopt(sk, SOL_TCP, TCP_REPAIR, &val, sizeof(val)))
		test_error("setsockopt(TCP_REPAIR)");
}

Annotation

Implementation Notes