Skip to content

Commit

Permalink
Merge branch 'mptcp-mib-counters-for-mpj-tx-misc-improvements'
Browse files Browse the repository at this point in the history
Matthieu Baerts says:

====================
mptcp: MIB counters for MPJ TX + misc improvements

Recently, a few issues have been discovered around the creation of
additional subflows. Without these counters, it was difficult to point
out the reason why some subflows were not created as expected.

In patch 3, all error paths from __mptcp_subflow_connect() are covered,
except the one related to the 'fully established mode', because it can
only happen with the userspace PM, which will propagate the error to the
userspace in this case (ENOTCONN).

These new counters are also verified in the MPTCP Join selftest in patch
6.

While at it, a few other patches are improving the MPTCP path-manager
code ...

 - Patch 1: 'flush' related helpers are renamed to avoid confusions
 - Patch 2: directly pass known ID and flags to create a new subflow,
            i/o getting them later by iterating over all endpoints again

... and the MPJoin selftests:

 - Patch 4: reduce the number of positional parameters
 - Patch 5: only one line for the 'join' checks, instead of 3
 - Patch 7: more explicit check names, instead of sometimes too cryptic
            ones: rtx, ptx, ftx, ctx, fclzrx, sum
 - Patch 8: specify client/server instead of 'invert' for some checks
            not suggesting one specific direction
 - Patch 9: mute errors of mptcp_connect when ran in the background
 - Patch 10: simplify checksum_tests by using a for-loop
 - Patch 11: remove 'define' re-definitions
====================

Link: https://patch.msgid.link/20240902-net-next-mptcp-mib-mpjtx-misc-v1-0-d3e0f3773b90@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Jakub Kicinski committed Sep 3, 2024
2 parents 8ecf2af + 38dc070 commit 1232e93
Show file tree
Hide file tree
Showing 9 changed files with 309 additions and 254 deletions.
4 changes: 4 additions & 0 deletions net/mptcp/mib.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ static const struct snmp_mib mptcp_snmp_list[] = {
SNMP_MIB_ITEM("MPJoinSynAckHMacFailure", MPTCP_MIB_JOINSYNACKMAC),
SNMP_MIB_ITEM("MPJoinAckRx", MPTCP_MIB_JOINACKRX),
SNMP_MIB_ITEM("MPJoinAckHMacFailure", MPTCP_MIB_JOINACKMAC),
SNMP_MIB_ITEM("MPJoinSynTx", MPTCP_MIB_JOINSYNTX),
SNMP_MIB_ITEM("MPJoinSynTxCreatSkErr", MPTCP_MIB_JOINSYNTXCREATSKERR),
SNMP_MIB_ITEM("MPJoinSynTxBindErr", MPTCP_MIB_JOINSYNTXBINDERR),
SNMP_MIB_ITEM("MPJoinSynTxConnectErr", MPTCP_MIB_JOINSYNTXCONNECTERR),
SNMP_MIB_ITEM("DSSNotMatching", MPTCP_MIB_DSSNOMATCH),
SNMP_MIB_ITEM("InfiniteMapTx", MPTCP_MIB_INFINITEMAPTX),
SNMP_MIB_ITEM("InfiniteMapRx", MPTCP_MIB_INFINITEMAPRX),
Expand Down
4 changes: 4 additions & 0 deletions net/mptcp/mib.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ enum linux_mptcp_mib_field {
MPTCP_MIB_JOINSYNACKMAC, /* HMAC was wrong on SYN/ACK + MP_JOIN */
MPTCP_MIB_JOINACKRX, /* Received an ACK + MP_JOIN */
MPTCP_MIB_JOINACKMAC, /* HMAC was wrong on ACK + MP_JOIN */
MPTCP_MIB_JOINSYNTX, /* Sending a SYN + MP_JOIN */
MPTCP_MIB_JOINSYNTXCREATSKERR, /* Not able to create a socket when sending a SYN + MP_JOIN */
MPTCP_MIB_JOINSYNTXBINDERR, /* Not able to bind() the address when sending a SYN + MP_JOIN */
MPTCP_MIB_JOINSYNTXCONNECTERR, /* Not able to connect() when sending a SYN + MP_JOIN */
MPTCP_MIB_DSSNOMATCH, /* Received a new mapping that did not match the previous one */
MPTCP_MIB_INFINITEMAPTX, /* Sent an infinite mapping */
MPTCP_MIB_INFINITEMAPRX, /* Received an infinite mapping */
Expand Down
11 changes: 0 additions & 11 deletions net/mptcp/pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -430,17 +430,6 @@ bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common *skc)
return mptcp_pm_nl_is_backup(msk, &skc_local);
}

int mptcp_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk, unsigned int id,
u8 *flags, int *ifindex)
{
*flags = 0;
*ifindex = 0;

if (mptcp_pm_is_userspace(msk))
return mptcp_userspace_pm_get_flags_and_ifindex_by_id(msk, id, flags, ifindex);
return mptcp_pm_nl_get_flags_and_ifindex_by_id(msk, id, flags, ifindex);
}

int mptcp_pm_get_addr(struct sk_buff *skb, struct genl_info *info)
{
if (info->attrs[MPTCP_PM_ATTR_TOKEN])
Expand Down
78 changes: 30 additions & 48 deletions net/mptcp/pm_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ static bool lookup_subflow_by_daddr(const struct list_head *list,
static bool
select_local_address(const struct pm_nl_pernet *pernet,
const struct mptcp_sock *msk,
struct mptcp_pm_addr_entry *new_entry)
struct mptcp_pm_local *new_local)
{
struct mptcp_pm_addr_entry *entry;
bool found = false;
Expand All @@ -164,7 +164,9 @@ select_local_address(const struct pm_nl_pernet *pernet,
if (!test_bit(entry->addr.id, msk->pm.id_avail_bitmap))
continue;

*new_entry = *entry;
new_local->addr = entry->addr;
new_local->flags = entry->flags;
new_local->ifindex = entry->ifindex;
found = true;
break;
}
Expand All @@ -175,7 +177,7 @@ select_local_address(const struct pm_nl_pernet *pernet,

static bool
select_signal_address(struct pm_nl_pernet *pernet, const struct mptcp_sock *msk,
struct mptcp_pm_addr_entry *new_entry)
struct mptcp_pm_local *new_local)
{
struct mptcp_pm_addr_entry *entry;
bool found = false;
Expand All @@ -193,7 +195,9 @@ select_signal_address(struct pm_nl_pernet *pernet, const struct mptcp_sock *msk,
if (!(entry->flags & MPTCP_PM_ADDR_FLAG_SIGNAL))
continue;

*new_entry = *entry;
new_local->addr = entry->addr;
new_local->flags = entry->flags;
new_local->ifindex = entry->ifindex;
found = true;
break;
}
Expand Down Expand Up @@ -524,11 +528,11 @@ __lookup_addr(struct pm_nl_pernet *pernet, const struct mptcp_addr_info *info)
static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
{
struct sock *sk = (struct sock *)msk;
struct mptcp_pm_addr_entry local;
unsigned int add_addr_signal_max;
bool signal_and_subflow = false;
unsigned int local_addr_max;
struct pm_nl_pernet *pernet;
struct mptcp_pm_local local;
unsigned int subflows_max;

pernet = pm_nl_get_pernet(sock_net(sk));
Expand Down Expand Up @@ -629,7 +633,7 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)

spin_unlock_bh(&msk->pm.lock);
for (i = 0; i < nr; i++)
__mptcp_subflow_connect(sk, &local.addr, &addrs[i]);
__mptcp_subflow_connect(sk, &local, &addrs[i]);
spin_lock_bh(&msk->pm.lock);
}
mptcp_pm_nl_check_work_pending(msk);
Expand All @@ -650,7 +654,7 @@ static void mptcp_pm_nl_subflow_established(struct mptcp_sock *msk)
*/
static unsigned int fill_local_addresses_vec(struct mptcp_sock *msk,
struct mptcp_addr_info *remote,
struct mptcp_addr_info *addrs)
struct mptcp_pm_local *locals)
{
struct sock *sk = (struct sock *)msk;
struct mptcp_pm_addr_entry *entry;
Expand All @@ -673,13 +677,15 @@ static unsigned int fill_local_addresses_vec(struct mptcp_sock *msk,
continue;

if (msk->pm.subflows < subflows_max) {
msk->pm.subflows++;
addrs[i] = entry->addr;
locals[i].addr = entry->addr;
locals[i].flags = entry->flags;
locals[i].ifindex = entry->ifindex;

/* Special case for ID0: set the correct ID */
if (mptcp_addresses_equal(&entry->addr, &mpc_addr, entry->addr.port))
addrs[i].id = 0;
if (mptcp_addresses_equal(&locals[i].addr, &mpc_addr, locals[i].addr.port))
locals[i].addr.id = 0;

msk->pm.subflows++;
i++;
}
}
Expand All @@ -689,29 +695,27 @@ static unsigned int fill_local_addresses_vec(struct mptcp_sock *msk,
* 'IPADDRANY' local address
*/
if (!i) {
struct mptcp_addr_info local;

memset(&local, 0, sizeof(local));
local.family =
memset(&locals[i], 0, sizeof(locals[i]));
locals[i].addr.family =
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
remote->family == AF_INET6 &&
ipv6_addr_v4mapped(&remote->addr6) ? AF_INET :
#endif
remote->family;

if (!mptcp_pm_addr_families_match(sk, &local, remote))
if (!mptcp_pm_addr_families_match(sk, &locals[i].addr, remote))
return 0;

msk->pm.subflows++;
addrs[i++] = local;
i++;
}

return i;
}

static void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk)
{
struct mptcp_addr_info addrs[MPTCP_PM_ADDR_MAX];
struct mptcp_pm_local locals[MPTCP_PM_ADDR_MAX];
struct sock *sk = (struct sock *)msk;
unsigned int add_addr_accept_max;
struct mptcp_addr_info remote;
Expand Down Expand Up @@ -740,13 +744,13 @@ static void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk)
/* connect to the specified remote address, using whatever
* local address the routing configuration will pick.
*/
nr = fill_local_addresses_vec(msk, &remote, addrs);
nr = fill_local_addresses_vec(msk, &remote, locals);
if (nr == 0)
return;

spin_unlock_bh(&msk->pm.lock);
for (i = 0; i < nr; i++)
if (__mptcp_subflow_connect(sk, &addrs[i], &remote) == 0)
if (__mptcp_subflow_connect(sk, &locals[i], &remote) == 0)
sf_created = true;
spin_lock_bh(&msk->pm.lock);

Expand Down Expand Up @@ -1433,28 +1437,6 @@ int mptcp_pm_nl_add_addr_doit(struct sk_buff *skb, struct genl_info *info)
return ret;
}

int mptcp_pm_nl_get_flags_and_ifindex_by_id(struct mptcp_sock *msk, unsigned int id,
u8 *flags, int *ifindex)
{
struct mptcp_pm_addr_entry *entry;
struct sock *sk = (struct sock *)msk;
struct net *net = sock_net(sk);

/* No entries with ID 0 */
if (id == 0)
return 0;

rcu_read_lock();
entry = __lookup_addr_by_id(pm_nl_get_pernet(net), id);
if (entry) {
*flags = entry->flags;
*ifindex = entry->ifindex;
}
rcu_read_unlock();

return 0;
}

static bool remove_anno_list_by_saddr(struct mptcp_sock *msk,
const struct mptcp_addr_info *addr)
{
Expand Down Expand Up @@ -1672,8 +1654,8 @@ void mptcp_pm_remove_addrs(struct mptcp_sock *msk, struct list_head *rm_list)
}

/* Called from the in-kernel PM only */
static void mptcp_pm_remove_addrs_and_subflows(struct mptcp_sock *msk,
struct list_head *rm_list)
static void mptcp_pm_flush_addrs_and_subflows(struct mptcp_sock *msk,
struct list_head *rm_list)
{
struct mptcp_rm_list alist = { .nr = 0 }, slist = { .nr = 0 };
struct mptcp_pm_addr_entry *entry;
Expand Down Expand Up @@ -1701,8 +1683,8 @@ static void mptcp_pm_remove_addrs_and_subflows(struct mptcp_sock *msk,
spin_unlock_bh(&msk->pm.lock);
}

static void mptcp_nl_remove_addrs_list(struct net *net,
struct list_head *rm_list)
static void mptcp_nl_flush_addrs_list(struct net *net,
struct list_head *rm_list)
{
long s_slot = 0, s_num = 0;
struct mptcp_sock *msk;
Expand All @@ -1715,7 +1697,7 @@ static void mptcp_nl_remove_addrs_list(struct net *net,

if (!mptcp_pm_is_userspace(msk)) {
lock_sock(sk);
mptcp_pm_remove_addrs_and_subflows(msk, rm_list);
mptcp_pm_flush_addrs_and_subflows(msk, rm_list);
release_sock(sk);
}

Expand Down Expand Up @@ -1756,7 +1738,7 @@ int mptcp_pm_nl_flush_addrs_doit(struct sk_buff *skb, struct genl_info *info)
pernet->next_id = 1;
bitmap_zero(pernet->id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
spin_unlock_bh(&pernet->lock);
mptcp_nl_remove_addrs_list(sock_net(skb->sk), &free_list);
mptcp_nl_flush_addrs_list(sock_net(skb->sk), &free_list);
synchronize_rcu();
__flush_addrs(&free_list);
return 0;
Expand Down
40 changes: 13 additions & 27 deletions net/mptcp/pm_userspace.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,23 +119,6 @@ mptcp_userspace_pm_lookup_addr_by_id(struct mptcp_sock *msk, unsigned int id)
return NULL;
}

int mptcp_userspace_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk,
unsigned int id,
u8 *flags, int *ifindex)
{
struct mptcp_pm_addr_entry *match;

spin_lock_bh(&msk->pm.lock);
match = mptcp_userspace_pm_lookup_addr_by_id(msk, id);
spin_unlock_bh(&msk->pm.lock);
if (match) {
*flags = match->flags;
*ifindex = match->ifindex;
}

return 0;
}

int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk,
struct mptcp_addr_info *skc)
{
Expand Down Expand Up @@ -352,8 +335,9 @@ int mptcp_pm_nl_subflow_create_doit(struct sk_buff *skb, struct genl_info *info)
struct nlattr *raddr = info->attrs[MPTCP_PM_ATTR_ADDR_REMOTE];
struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN];
struct nlattr *laddr = info->attrs[MPTCP_PM_ATTR_ADDR];
struct mptcp_pm_addr_entry local = { 0 };
struct mptcp_pm_addr_entry entry = { 0 };
struct mptcp_addr_info addr_r;
struct mptcp_pm_local local;
struct mptcp_sock *msk;
int err = -EINVAL;
struct sock *sk;
Expand All @@ -379,46 +363,48 @@ int mptcp_pm_nl_subflow_create_doit(struct sk_buff *skb, struct genl_info *info)
goto create_err;
}

err = mptcp_pm_parse_entry(laddr, info, true, &local);
err = mptcp_pm_parse_entry(laddr, info, true, &entry);
if (err < 0) {
NL_SET_ERR_MSG_ATTR(info->extack, laddr, "error parsing local addr");
goto create_err;
}

if (local.flags & MPTCP_PM_ADDR_FLAG_SIGNAL) {
if (entry.flags & MPTCP_PM_ADDR_FLAG_SIGNAL) {
GENL_SET_ERR_MSG(info, "invalid addr flags");
err = -EINVAL;
goto create_err;
}
local.flags |= MPTCP_PM_ADDR_FLAG_SUBFLOW;
entry.flags |= MPTCP_PM_ADDR_FLAG_SUBFLOW;

err = mptcp_pm_parse_addr(raddr, info, &addr_r);
if (err < 0) {
NL_SET_ERR_MSG_ATTR(info->extack, raddr, "error parsing remote addr");
goto create_err;
}

if (!mptcp_pm_addr_families_match(sk, &local.addr, &addr_r)) {
if (!mptcp_pm_addr_families_match(sk, &entry.addr, &addr_r)) {
GENL_SET_ERR_MSG(info, "families mismatch");
err = -EINVAL;
goto create_err;
}

err = mptcp_userspace_pm_append_new_local_addr(msk, &local, false);
err = mptcp_userspace_pm_append_new_local_addr(msk, &entry, false);
if (err < 0) {
GENL_SET_ERR_MSG(info, "did not match address and id");
goto create_err;
}

lock_sock(sk);

err = __mptcp_subflow_connect(sk, &local.addr, &addr_r);
local.addr = entry.addr;
local.flags = entry.flags;
local.ifindex = entry.ifindex;

lock_sock(sk);
err = __mptcp_subflow_connect(sk, &local, &addr_r);
release_sock(sk);

spin_lock_bh(&msk->pm.lock);
if (err)
mptcp_userspace_pm_delete_local_addr(msk, &local);
mptcp_userspace_pm_delete_local_addr(msk, &entry);
else
msk->pm.subflows++;
spin_unlock_bh(&msk->pm.lock);
Expand Down
16 changes: 7 additions & 9 deletions net/mptcp/protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,12 @@ struct mptcp_pm_data {
struct mptcp_rm_list rm_list_rx;
};

struct mptcp_pm_local {
struct mptcp_addr_info addr;
u8 flags;
int ifindex;
};

struct mptcp_pm_addr_entry {
struct list_head list;
struct mptcp_addr_info addr;
Expand Down Expand Up @@ -719,7 +725,7 @@ bool mptcp_addresses_equal(const struct mptcp_addr_info *a,
void mptcp_local_address(const struct sock_common *skc, struct mptcp_addr_info *addr);

/* called with sk socket lock held */
int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc,
int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_pm_local *local,
const struct mptcp_addr_info *remote);
int mptcp_subflow_create_socket(struct sock *sk, unsigned short family,
struct socket **new_sock);
Expand Down Expand Up @@ -1014,14 +1020,6 @@ mptcp_pm_del_add_timer(struct mptcp_sock *msk,
struct mptcp_pm_add_entry *
mptcp_lookup_anno_list_by_saddr(const struct mptcp_sock *msk,
const struct mptcp_addr_info *addr);
int mptcp_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk,
unsigned int id,
u8 *flags, int *ifindex);
int mptcp_pm_nl_get_flags_and_ifindex_by_id(struct mptcp_sock *msk, unsigned int id,
u8 *flags, int *ifindex);
int mptcp_userspace_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk,
unsigned int id,
u8 *flags, int *ifindex);
int mptcp_pm_set_flags(struct sk_buff *skb, struct genl_info *info);
int mptcp_pm_nl_set_flags(struct sk_buff *skb, struct genl_info *info);
int mptcp_userspace_pm_set_flags(struct sk_buff *skb, struct genl_info *info);
Expand Down
Loading

0 comments on commit 1232e93

Please sign in to comment.