Commit ca188a25 authored by Kishen Maloor's avatar Kishen Maloor Committed by David S. Miller
Browse files

selftests: mptcp: userspace PM support for MP_PRIO signals



This change updates the testing sample (pm_nl_ctl) to exercise
the updated MPTCP_PM_CMD_SET_FLAGS command for userspace PMs to
issue MP_PRIO signals over the selected subflow.

E.g. ./pm_nl_ctl set 10.0.1.2 port 47234 flags backup token 823274047 rip 10.0.1.1 rport 50003

userspace_pm.sh has a new selftest that invokes this command.

Fixes: 259a834f ("selftests: mptcp: functional tests for the userspace PM type")
Acked-by: default avatarPaolo Abeni <pabeni@redhat.com>
Signed-off-by: default avatarKishen Maloor <kishen.maloor@intel.com>
Signed-off-by: default avatarMat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 892f396c
Loading
Loading
Loading
Loading
+71 −2
Original line number Diff line number Diff line
@@ -39,7 +39,7 @@ static void syntax(char *argv[])
	fprintf(stderr, "\tdsf lip <local-ip> lport <local-port> rip <remote-ip> rport <remote-port> token <token>\n");
	fprintf(stderr, "\tdel <id> [<ip>]\n");
	fprintf(stderr, "\tget <id>\n");
	fprintf(stderr, "\tset [<ip>] [id <nr>] flags [no]backup|[no]fullmesh [port <nr>]\n");
	fprintf(stderr, "\tset [<ip>] [id <nr>] flags [no]backup|[no]fullmesh [port <nr>] [token <token>] [rip <ip>] [rport <port>]\n");
	fprintf(stderr, "\tflush\n");
	fprintf(stderr, "\tdump\n");
	fprintf(stderr, "\tlimits [<rcv addr max> <subflow max>]\n");
@@ -1279,7 +1279,10 @@ int set_flags(int fd, int pm_family, int argc, char *argv[])
	struct rtattr *rta, *nest;
	struct nlmsghdr *nh;
	u_int32_t flags = 0;
	u_int32_t token = 0;
	u_int16_t rport = 0;
	u_int16_t family;
	void *rip = NULL;
	int nest_start;
	int use_id = 0;
	u_int8_t id;
@@ -1339,7 +1342,13 @@ int set_flags(int fd, int pm_family, int argc, char *argv[])
		error(1, 0, " missing flags keyword");

	for (; arg < argc; arg++) {
		if (!strcmp(argv[arg], "flags")) {
		if (!strcmp(argv[arg], "token")) {
			if (++arg >= argc)
				error(1, 0, " missing token value");

			/* token */
			token = atoi(argv[arg]);
		} else if (!strcmp(argv[arg], "flags")) {
			char *tok, *str;

			/* flags */
@@ -1378,12 +1387,72 @@ int set_flags(int fd, int pm_family, int argc, char *argv[])
			rta->rta_len = RTA_LENGTH(2);
			memcpy(RTA_DATA(rta), &port, 2);
			off += NLMSG_ALIGN(rta->rta_len);
		} else if (!strcmp(argv[arg], "rport")) {
			if (++arg >= argc)
				error(1, 0, " missing remote port");

			rport = atoi(argv[arg]);
		} else if (!strcmp(argv[arg], "rip")) {
			if (++arg >= argc)
				error(1, 0, " missing remote ip");

			rip = argv[arg];
		} else {
			error(1, 0, "unknown keyword %s", argv[arg]);
		}
	}
	nest->rta_len = off - nest_start;

	/* token */
	if (token) {
		rta = (void *)(data + off);
		rta->rta_type = MPTCP_PM_ATTR_TOKEN;
		rta->rta_len = RTA_LENGTH(4);
		memcpy(RTA_DATA(rta), &token, 4);
		off += NLMSG_ALIGN(rta->rta_len);
	}

	/* remote addr/port */
	if (rip) {
		nest_start = off;
		nest = (void *)(data + off);
		nest->rta_type = NLA_F_NESTED | MPTCP_PM_ATTR_ADDR_REMOTE;
		nest->rta_len = RTA_LENGTH(0);
		off += NLMSG_ALIGN(nest->rta_len);

		/* addr data */
		rta = (void *)(data + off);
		if (inet_pton(AF_INET, rip, RTA_DATA(rta))) {
			family = AF_INET;
			rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR4;
			rta->rta_len = RTA_LENGTH(4);
		} else if (inet_pton(AF_INET6, rip, RTA_DATA(rta))) {
			family = AF_INET6;
			rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR6;
			rta->rta_len = RTA_LENGTH(16);
		} else {
			error(1, errno, "can't parse ip %s", (char *)rip);
		}
		off += NLMSG_ALIGN(rta->rta_len);

		/* family */
		rta = (void *)(data + off);
		rta->rta_type = MPTCP_PM_ADDR_ATTR_FAMILY;
		rta->rta_len = RTA_LENGTH(2);
		memcpy(RTA_DATA(rta), &family, 2);
		off += NLMSG_ALIGN(rta->rta_len);

		if (rport) {
			rta = (void *)(data + off);
			rta->rta_type = MPTCP_PM_ADDR_ATTR_PORT;
			rta->rta_len = RTA_LENGTH(2);
			memcpy(RTA_DATA(rta), &rport, 2);
			off += NLMSG_ALIGN(rta->rta_len);
		}

		nest->rta_len = off - nest_start;
	}

	do_nl_req(fd, nh, off, 0);
	return 0;
}
+32 −0
Original line number Diff line number Diff line
@@ -770,10 +770,42 @@ test_subflows()
	rm -f "$evts"
}

test_prio()
{
	local count

	# Send MP_PRIO signal from client to server machine
	ip netns exec "$ns2" ./pm_nl_ctl set 10.0.1.2 port "$client4_port" flags backup token "$client4_token" rip 10.0.1.1 rport "$server4_port"
	sleep 0.5

	# Check TX
	stdbuf -o0 -e0 printf "MP_PRIO TX                                                 \t"
	count=$(ip netns exec "$ns2" nstat -as | grep MPTcpExtMPPrioTx | awk '{print $2}')
	[ -z "$count" ] && count=0
	if [ $count != 1 ]; then
		stdbuf -o0 -e0 printf "[FAIL]\n"
		exit 1
	else
		stdbuf -o0 -e0 printf "[OK]\n"
	fi

	# Check RX
	stdbuf -o0 -e0 printf "MP_PRIO RX                                                 \t"
	count=$(ip netns exec "$ns1" nstat -as | grep MPTcpExtMPPrioRx | awk '{print $2}')
	[ -z "$count" ] && count=0
	if [ $count != 1 ]; then
		stdbuf -o0 -e0 printf "[FAIL]\n"
		exit 1
	else
		stdbuf -o0 -e0 printf "[OK]\n"
	fi
}

make_connection
make_connection "v6"
test_announce
test_remove
test_subflows
test_prio

exit 0