mptcp: add support for port based endpoint

The feature is supported by the kernel since 5.11-net-next,
let's allow user-space to use it.

Just parse and dump an additional, per endpoint, u16 attribute

Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: David Ahern <dsahern@kernel.org>
This commit is contained in:
Paolo Abeni 2021-02-19 21:42:55 +01:00 committed by David Ahern
parent 455c9f5361
commit 42fbca91cd
2 changed files with 22 additions and 2 deletions

View File

@ -17,7 +17,7 @@ static void usage(void)
{ {
fprintf(stderr, fprintf(stderr,
"Usage: ip mptcp endpoint add ADDRESS [ dev NAME ] [ id ID ]\n" "Usage: ip mptcp endpoint add ADDRESS [ dev NAME ] [ id ID ]\n"
" [ FLAG-LIST ]\n" " [ port NR ] [ FLAG-LIST ]\n"
" ip mptcp endpoint delete id ID\n" " ip mptcp endpoint delete id ID\n"
" ip mptcp endpoint show [ id ID ]\n" " ip mptcp endpoint show [ id ID ]\n"
" ip mptcp endpoint flush\n" " ip mptcp endpoint flush\n"
@ -97,6 +97,7 @@ static int mptcp_parse_opt(int argc, char **argv, struct nlmsghdr *n,
bool id_set = false; bool id_set = false;
__u32 index = 0; __u32 index = 0;
__u32 flags = 0; __u32 flags = 0;
__u16 port = 0;
__u8 id = 0; __u8 id = 0;
ll_init_map(&rth); ll_init_map(&rth);
@ -123,6 +124,10 @@ static int mptcp_parse_opt(int argc, char **argv, struct nlmsghdr *n,
if (!index) if (!index)
invarg("device does not exist\n", ifname); invarg("device does not exist\n", ifname);
} else if (matches(*argv, "port") == 0) {
NEXT_ARG();
if (get_u16(&port, *argv, 0))
invarg("expected port", *argv);
} else if (get_addr(&address, *argv, AF_UNSPEC) == 0) { } else if (get_addr(&address, *argv, AF_UNSPEC) == 0) {
addr_set = true; addr_set = true;
} else { } else {
@ -145,6 +150,8 @@ static int mptcp_parse_opt(int argc, char **argv, struct nlmsghdr *n,
addattr32(n, MPTCP_BUFLEN, MPTCP_PM_ADDR_ATTR_FLAGS, flags); addattr32(n, MPTCP_BUFLEN, MPTCP_PM_ADDR_ATTR_FLAGS, flags);
if (index) if (index)
addattr32(n, MPTCP_BUFLEN, MPTCP_PM_ADDR_ATTR_IF_IDX, index); addattr32(n, MPTCP_BUFLEN, MPTCP_PM_ADDR_ATTR_IF_IDX, index);
if (port)
addattr16(n, MPTCP_BUFLEN, MPTCP_PM_ADDR_ATTR_PORT, port);
if (addr_set) { if (addr_set) {
int type; int type;
@ -181,8 +188,8 @@ static int print_mptcp_addrinfo(struct rtattr *addrinfo)
__u8 family = AF_UNSPEC, addr_attr_type; __u8 family = AF_UNSPEC, addr_attr_type;
const char *ifname; const char *ifname;
unsigned int flags; unsigned int flags;
__u16 id, port;
int index; int index;
__u16 id;
parse_rtattr_nested(tb, MPTCP_PM_ADDR_ATTR_MAX, addrinfo); parse_rtattr_nested(tb, MPTCP_PM_ADDR_ATTR_MAX, addrinfo);
@ -196,6 +203,11 @@ static int print_mptcp_addrinfo(struct rtattr *addrinfo)
print_string(PRINT_ANY, "address", "%s ", print_string(PRINT_ANY, "address", "%s ",
format_host_rta(family, tb[addr_attr_type])); format_host_rta(family, tb[addr_attr_type]));
} }
if (tb[MPTCP_PM_ADDR_ATTR_PORT]) {
port = rta_getattr_u16(tb[MPTCP_PM_ADDR_ATTR_PORT]);
if (port)
print_uint(PRINT_ANY, "port", "port %u ", port);
}
if (tb[MPTCP_PM_ADDR_ATTR_ID]) { if (tb[MPTCP_PM_ADDR_ATTR_ID]) {
id = rta_getattr_u8(tb[MPTCP_PM_ADDR_ATTR_ID]); id = rta_getattr_u8(tb[MPTCP_PM_ADDR_ATTR_ID]);
print_uint(PRINT_ANY, "id", "id %u ", id); print_uint(PRINT_ANY, "id", "id %u ", id);

View File

@ -20,6 +20,8 @@ ip-mptcp \- MPTCP path manager configuration
.ti -8 .ti -8
.BR "ip mptcp endpoint add " .BR "ip mptcp endpoint add "
.IR IFADDR .IR IFADDR
.RB "[ " port
.IR PORT " ]"
.RB "[ " dev .RB "[ " dev
.IR IFNAME " ]" .IR IFNAME " ]"
.RB "[ " id .RB "[ " id
@ -87,6 +89,12 @@ ip mptcp endpoint flush flush all existing MPTCP endpoints
.TE .TE
.TP .TP
.IR PORT
When a port number is specified, incoming MPTCP subflows for already
established MPTCP sockets will be accepted on the specified port, regardless
the original listener port accepting the first MPTCP subflow and/or
this peer being actually on the client side.
.IR ID .IR ID
is a unique numeric identifier for the given endpoint is a unique numeric identifier for the given endpoint