tools/testing/selftests/net/ipv6_flowlabel.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/net/ipv6_flowlabel.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/net/ipv6_flowlabel.c
Extension
.c
Size
6232 bytes
Lines
275
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 (expect != FLOWLABEL_WILDCARD && expect != flowlabel) {
			fprintf(stderr, "recv: incorrect flowlabel %u != %u\n",
					flowlabel, expect);
			error(1, 0, "recv: flowlabel is wrong");
		}

	} else {
		fprintf(stderr, "recv without label\n");
	}
}

static bool get_autoflowlabel_enabled(void)
{
	int fd, ret;
	char val;

	fd = open("/proc/sys/net/ipv6/auto_flowlabels", O_RDONLY);
	if (fd == -1)
		error(1, errno, "open sysctl");

	ret = read(fd, &val, 1);
	if (ret == -1)
		error(1, errno, "read sysctl");
	if (ret == 0)
		error(1, 0, "read sysctl: 0");

	if (close(fd))
		error(1, errno, "close sysctl");

	return val == '1';
}

static void flowlabel_get(int fd, uint32_t label, uint8_t share, uint16_t flags)
{
	struct in6_flowlabel_req req = {
		.flr_action = IPV6_FL_A_GET,
		.flr_label = htonl(label),
		.flr_flags = flags,
		.flr_share = share,
	};

	/* do not pass IPV6_ADDR_ANY or IPV6_ADDR_MAPPED */
	req.flr_dst.s6_addr[0] = 0xfd;
	req.flr_dst.s6_addr[15] = 0x1;

	if (setsockopt(fd, SOL_IPV6, IPV6_FLOWLABEL_MGR, &req, sizeof(req)))
		error(1, errno, "setsockopt flowlabel get");
}

static void parse_opts(int argc, char **argv)
{
	int c;

	while ((c = getopt(argc, argv, "l:ps")) != -1) {
		switch (c) {
		case 'l':
			cfg_label = strtoul(optarg, NULL, 0);
			break;
		case 'p':
			use_ping = true;
			break;
		case 's':
			use_flowinfo_send = true;
			break;
		default:
			error(1, 0, "%s: parse error", argv[0]);
		}
	}
}

int main(int argc, char **argv)
{
	const int one = 1;
	int fdt, fdr;
	int prot = 0;

	addr.sin6_port = htons(8000);

	parse_opts(argc, argv);

	if (use_ping) {
		fprintf(stderr, "attempting to use ping sockets\n");
		prot = IPPROTO_ICMPV6;
	}

	fdt = socket(PF_INET6, SOCK_DGRAM, prot);
	if (fdt == -1)
		error(1, errno, "socket t");

	fdr = use_ping ? fdt : socket(PF_INET6, SOCK_DGRAM, 0);

Annotation

Implementation Notes