Skip to content

Commit

Permalink
Implement support for upstream kernel "set_flags". (#116)
Browse files Browse the repository at this point in the history
Implement support for the MPTCP_PM_CMD_SET_FLAGS command found in
recent versions of the upstream Linux kernel's MPTCP generic netlink
path management API.
  • Loading branch information
Ossama Othman authored Apr 8, 2021
1 parent f9b951f commit daf9c24
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 4 deletions.
4 changes: 2 additions & 2 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ AC_INIT([mptcpd],
# Interfaces changed: CURRENT++ REVISION=0
# added: CURRENT++ REVISION=0 AGE++
# removed: CURRENT++ REVISION=0 AGE=0
LIB_CURRENT=1
LIB_CURRENT=2
LIB_REVISION=0
LIB_AGE=0
LIB_AGE=1

AC_SUBST([LIB_CURRENT])
AC_SUBST([LIB_REVISION])
Expand Down
13 changes: 13 additions & 0 deletions include/mptcpd/path_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,19 @@ MPTCPD_API int mptcpd_pm_set_limits(struct mptcpd_pm *pm,
struct mptcpd_limit const *limits,
size_t len);

/**
* @brief Set MPTCP resource limits.
*
* @param[in] pm The mptcpd path manager object.
* @param[in] addr Local IP address.
* @param[in] flags Flags to be associated with @a addr.
*
* @return @c 0 if operation was successful. -1 or @c errno otherwise.
*/
MPTCPD_API int mptcpd_pm_set_flags(struct mptcpd_pm *pm,
struct sockaddr const *addr,
mptcpd_flags_t flags);

/**
* @brief Get MPTCP resource limits.
*
Expand Down
11 changes: 11 additions & 0 deletions include/mptcpd/private/path_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,17 @@ struct mptcpd_pm_cmd_ops
int (*get_limits)(struct mptcpd_pm *pm,
mptcpd_pm_get_limits_cb callback,
void *data);

/**
* @brief
*
* @param[in] pm The mptcpd path manager object.
* @param[in] addr Local IP address information.
* @param[in] flags Flags to be associated with @a addr.
*/
int (*set_flags)(struct mptcpd_pm *pm,
struct sockaddr const *addr,
mptcpd_flags_t flags);
//@}

/**
Expand Down
28 changes: 27 additions & 1 deletion include/mptcpd/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,35 @@ typedef uint8_t mptcpd_aid_t;
/// MPTCP address ID format specifier.
#define MPTCPD_PRIxAID PRIx8

/// MPTCP flags type.
/**
* @name MPTCP Address Flags
*
* Each MPTCP address flag is meant to be set as a bit in a
* @c mptcpd_flags_t variable as needed, e.g.:
*
* @code
* mptcpd_flags_t flags =
* MPTCPD_ADDR_FLAG_SUBFLOW | MPTCPD_ADDR_FLAG_BACKUP;
* @endcode
*/
//@{
/**
* @brief MPTCP flags type.
*
* MPTCP address flags integer type that contains set of flag bits.
*/
typedef uint32_t mptcpd_flags_t;

///
#define MPTCPD_ADDR_FLAG_SIGNAL (1U << 0)

///
#define MPTCPD_ADDR_FLAG_SUBFLOW (1U << 1)

///
#define MPTCPD_ADDR_FLAG_BACKUP (1U << 2)
//@}

/**
* @enum mptcp_limit_types
*
Expand Down
19 changes: 19 additions & 0 deletions lib/path_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,25 @@ int mptcpd_pm_get_limits(struct mptcpd_pm *pm,
return ops->get_limits(pm, callback, data);
}

int mptcpd_pm_set_flags(struct mptcpd_pm *pm,
struct sockaddr const *addr,
mptcpd_flags_t flags)
{
if (pm == NULL || addr == NULL)
return EINVAL;

if (!is_pm_ready(pm, __func__))
return EAGAIN;

struct mptcpd_pm_cmd_ops const *const ops =
pm->netlink_pm->cmd_ops;

if (ops->set_flags == NULL)
return ENOTSUP;

return ops->set_flags(pm, addr, flags);
}

int mptcpd_pm_add_subflow(struct mptcpd_pm *pm,
mptcpd_token_t token,
mptcpd_aid_t local_address_id,
Expand Down
61 changes: 60 additions & 1 deletion src/netlink_pm_upstream.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@
#include "commands.h"
#include "path_manager.h"

// Sanity check
#if MPTCPD_ADDR_FLAG_SIGNAL != MPTCP_PM_ADDR_FLAG_SIGNAL \
|| MPTCPD_ADDR_FLAG_SUBFLOW != MPTCP_PM_ADDR_FLAG_SUBFLOW \
|| MPTCPD_ADDR_FLAG_BACKUP != MPTCP_PM_ADDR_FLAG_BACKUP
# error Mismatch between mptcpd and upstream kernel addr flags.
#endif

/**
* @struct get_addr_user_callback
Expand Down Expand Up @@ -622,6 +628,58 @@ static int upstream_get_limits(struct mptcpd_pm *pm,
l_free /* destroy */) == 0;
}

static int upstream_set_flags(struct mptcpd_pm *pm,
struct sockaddr const *addr,
mptcpd_flags_t flags)
{
/*
Payload (nested):
Local address family
Local address
Flags
*/

// Types chosen to match MPTCP genl API.
uint16_t const family = mptcpd_get_addr_family(addr);

size_t const payload_size =
MPTCPD_NLA_ALIGN(family)
+ MPTCPD_NLA_ALIGN_ADDR(addr)
+ MPTCPD_NLA_ALIGN(flags);

struct l_genl_msg *const msg =
l_genl_msg_new_sized(MPTCP_PM_CMD_SET_FLAGS,
payload_size);

bool const appended =
l_genl_msg_enter_nested(msg,
NLA_F_NESTED | MPTCP_PM_ATTR_ADDR)
&& l_genl_msg_append_attr(
msg,
MPTCP_PM_ADDR_ATTR_FAMILY,
sizeof(family), // sizeof(uint16_t)
&family)
&& append_addr_attr(msg, addr)
&& l_genl_msg_append_attr(
msg,
MPTCP_PM_ADDR_ATTR_FLAGS,
sizeof(flags), // sizeof(uint32_t)
&flags)
&& l_genl_msg_leave_nested(msg);

if (!appended) {
l_genl_msg_unref(msg);

return ENOMEM;
}

return l_genl_family_send(pm->family,
msg,
mptcpd_family_send_callback,
"set_flags", /* user data */
NULL /* destroy */) == 0;
}

static struct mptcpd_pm_cmd_ops const cmd_ops =
{
.add_addr = upstream_add_addr,
Expand All @@ -630,7 +688,8 @@ static struct mptcpd_pm_cmd_ops const cmd_ops =
.dump_addrs = upstream_dump_addrs,
.flush_addrs = upstream_flush_addrs,
.set_limits = upstream_set_limits,
.get_limits = upstream_get_limits
.get_limits = upstream_get_limits,
.set_flags = upstream_set_flags,
};

static struct mptcpd_netlink_pm const npm = {
Expand Down
15 changes: 15 additions & 0 deletions tests/test-commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,20 @@ static void test_get_limits(void const *test_data)
assert(result == 0 || result == ENOTSUP);
}

static void test_set_flags(void const *test_data)
{
struct mptcpd_pm *const pm = (struct mptcpd_pm *) test_data;

if (!is_pm_ready(pm, __func__))
return;

static mptcpd_flags_t const flags = MPTCPD_ADDR_FLAG_BACKUP;

int const result = mptcpd_pm_set_flags(pm, laddr1, flags);

assert(result == 0 || result == ENOTSUP);
}

static void test_add_subflow(void const *test_data)
{
struct mptcpd_pm *const pm = (struct mptcpd_pm *) test_data;
Expand Down Expand Up @@ -412,6 +426,7 @@ int main(void)
l_test_add("remove_addr", test_remove_addr, pm);
l_test_add("set_limits", test_set_limits, pm);
l_test_add("get_limits", test_get_limits, pm);
l_test_add("set_flags", test_set_flags, pm);
l_test_add("add_subflow", test_add_subflow, pm);
l_test_add("set_backup", test_set_backup, pm);
l_test_add("remove_subflow", test_remove_subflow, pm);
Expand Down

0 comments on commit daf9c24

Please sign in to comment.