Skip to content

Commit daf9c24

Browse files
author
Ossama Othman
authored
Implement support for upstream kernel "set_flags". (#116)
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.
1 parent f9b951f commit daf9c24

File tree

7 files changed

+147
-4
lines changed

7 files changed

+147
-4
lines changed

configure.ac

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ AC_INIT([mptcpd],
1818
# Interfaces changed: CURRENT++ REVISION=0
1919
# added: CURRENT++ REVISION=0 AGE++
2020
# removed: CURRENT++ REVISION=0 AGE=0
21-
LIB_CURRENT=1
21+
LIB_CURRENT=2
2222
LIB_REVISION=0
23-
LIB_AGE=0
23+
LIB_AGE=1
2424

2525
AC_SUBST([LIB_CURRENT])
2626
AC_SUBST([LIB_REVISION])

include/mptcpd/path_manager.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,19 @@ MPTCPD_API int mptcpd_pm_set_limits(struct mptcpd_pm *pm,
207207
struct mptcpd_limit const *limits,
208208
size_t len);
209209

210+
/**
211+
* @brief Set MPTCP resource limits.
212+
*
213+
* @param[in] pm The mptcpd path manager object.
214+
* @param[in] addr Local IP address.
215+
* @param[in] flags Flags to be associated with @a addr.
216+
*
217+
* @return @c 0 if operation was successful. -1 or @c errno otherwise.
218+
*/
219+
MPTCPD_API int mptcpd_pm_set_flags(struct mptcpd_pm *pm,
220+
struct sockaddr const *addr,
221+
mptcpd_flags_t flags);
222+
210223
/**
211224
* @brief Get MPTCP resource limits.
212225
*

include/mptcpd/private/path_manager.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,17 @@ struct mptcpd_pm_cmd_ops
248248
int (*get_limits)(struct mptcpd_pm *pm,
249249
mptcpd_pm_get_limits_cb callback,
250250
void *data);
251+
252+
/**
253+
* @brief
254+
*
255+
* @param[in] pm The mptcpd path manager object.
256+
* @param[in] addr Local IP address information.
257+
* @param[in] flags Flags to be associated with @a addr.
258+
*/
259+
int (*set_flags)(struct mptcpd_pm *pm,
260+
struct sockaddr const *addr,
261+
mptcpd_flags_t flags);
251262
//@}
252263

253264
/**

include/mptcpd/types.h

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,35 @@ typedef uint8_t mptcpd_aid_t;
3131
/// MPTCP address ID format specifier.
3232
#define MPTCPD_PRIxAID PRIx8
3333

34-
/// MPTCP flags type.
34+
/**
35+
* @name MPTCP Address Flags
36+
*
37+
* Each MPTCP address flag is meant to be set as a bit in a
38+
* @c mptcpd_flags_t variable as needed, e.g.:
39+
*
40+
* @code
41+
* mptcpd_flags_t flags =
42+
* MPTCPD_ADDR_FLAG_SUBFLOW | MPTCPD_ADDR_FLAG_BACKUP;
43+
* @endcode
44+
*/
45+
//@{
46+
/**
47+
* @brief MPTCP flags type.
48+
*
49+
* MPTCP address flags integer type that contains set of flag bits.
50+
*/
3551
typedef uint32_t mptcpd_flags_t;
3652

53+
///
54+
#define MPTCPD_ADDR_FLAG_SIGNAL (1U << 0)
55+
56+
///
57+
#define MPTCPD_ADDR_FLAG_SUBFLOW (1U << 1)
58+
59+
///
60+
#define MPTCPD_ADDR_FLAG_BACKUP (1U << 2)
61+
//@}
62+
3763
/**
3864
* @enum mptcp_limit_types
3965
*

lib/path_manager.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,25 @@ int mptcpd_pm_get_limits(struct mptcpd_pm *pm,
214214
return ops->get_limits(pm, callback, data);
215215
}
216216

217+
int mptcpd_pm_set_flags(struct mptcpd_pm *pm,
218+
struct sockaddr const *addr,
219+
mptcpd_flags_t flags)
220+
{
221+
if (pm == NULL || addr == NULL)
222+
return EINVAL;
223+
224+
if (!is_pm_ready(pm, __func__))
225+
return EAGAIN;
226+
227+
struct mptcpd_pm_cmd_ops const *const ops =
228+
pm->netlink_pm->cmd_ops;
229+
230+
if (ops->set_flags == NULL)
231+
return ENOTSUP;
232+
233+
return ops->set_flags(pm, addr, flags);
234+
}
235+
217236
int mptcpd_pm_add_subflow(struct mptcpd_pm *pm,
218237
mptcpd_token_t token,
219238
mptcpd_aid_t local_address_id,

src/netlink_pm_upstream.c

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@
3030
#include "commands.h"
3131
#include "path_manager.h"
3232

33+
// Sanity check
34+
#if MPTCPD_ADDR_FLAG_SIGNAL != MPTCP_PM_ADDR_FLAG_SIGNAL \
35+
|| MPTCPD_ADDR_FLAG_SUBFLOW != MPTCP_PM_ADDR_FLAG_SUBFLOW \
36+
|| MPTCPD_ADDR_FLAG_BACKUP != MPTCP_PM_ADDR_FLAG_BACKUP
37+
# error Mismatch between mptcpd and upstream kernel addr flags.
38+
#endif
3339

3440
/**
3541
* @struct get_addr_user_callback
@@ -622,6 +628,58 @@ static int upstream_get_limits(struct mptcpd_pm *pm,
622628
l_free /* destroy */) == 0;
623629
}
624630

631+
static int upstream_set_flags(struct mptcpd_pm *pm,
632+
struct sockaddr const *addr,
633+
mptcpd_flags_t flags)
634+
{
635+
/*
636+
Payload (nested):
637+
Local address family
638+
Local address
639+
Flags
640+
*/
641+
642+
// Types chosen to match MPTCP genl API.
643+
uint16_t const family = mptcpd_get_addr_family(addr);
644+
645+
size_t const payload_size =
646+
MPTCPD_NLA_ALIGN(family)
647+
+ MPTCPD_NLA_ALIGN_ADDR(addr)
648+
+ MPTCPD_NLA_ALIGN(flags);
649+
650+
struct l_genl_msg *const msg =
651+
l_genl_msg_new_sized(MPTCP_PM_CMD_SET_FLAGS,
652+
payload_size);
653+
654+
bool const appended =
655+
l_genl_msg_enter_nested(msg,
656+
NLA_F_NESTED | MPTCP_PM_ATTR_ADDR)
657+
&& l_genl_msg_append_attr(
658+
msg,
659+
MPTCP_PM_ADDR_ATTR_FAMILY,
660+
sizeof(family), // sizeof(uint16_t)
661+
&family)
662+
&& append_addr_attr(msg, addr)
663+
&& l_genl_msg_append_attr(
664+
msg,
665+
MPTCP_PM_ADDR_ATTR_FLAGS,
666+
sizeof(flags), // sizeof(uint32_t)
667+
&flags)
668+
&& l_genl_msg_leave_nested(msg);
669+
670+
if (!appended) {
671+
l_genl_msg_unref(msg);
672+
673+
return ENOMEM;
674+
}
675+
676+
return l_genl_family_send(pm->family,
677+
msg,
678+
mptcpd_family_send_callback,
679+
"set_flags", /* user data */
680+
NULL /* destroy */) == 0;
681+
}
682+
625683
static struct mptcpd_pm_cmd_ops const cmd_ops =
626684
{
627685
.add_addr = upstream_add_addr,
@@ -630,7 +688,8 @@ static struct mptcpd_pm_cmd_ops const cmd_ops =
630688
.dump_addrs = upstream_dump_addrs,
631689
.flush_addrs = upstream_flush_addrs,
632690
.set_limits = upstream_set_limits,
633-
.get_limits = upstream_get_limits
691+
.get_limits = upstream_get_limits,
692+
.set_flags = upstream_set_flags,
634693
};
635694

636695
static struct mptcpd_netlink_pm const npm = {

tests/test-commands.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,20 @@ static void test_get_limits(void const *test_data)
261261
assert(result == 0 || result == ENOTSUP);
262262
}
263263

264+
static void test_set_flags(void const *test_data)
265+
{
266+
struct mptcpd_pm *const pm = (struct mptcpd_pm *) test_data;
267+
268+
if (!is_pm_ready(pm, __func__))
269+
return;
270+
271+
static mptcpd_flags_t const flags = MPTCPD_ADDR_FLAG_BACKUP;
272+
273+
int const result = mptcpd_pm_set_flags(pm, laddr1, flags);
274+
275+
assert(result == 0 || result == ENOTSUP);
276+
}
277+
264278
static void test_add_subflow(void const *test_data)
265279
{
266280
struct mptcpd_pm *const pm = (struct mptcpd_pm *) test_data;
@@ -412,6 +426,7 @@ int main(void)
412426
l_test_add("remove_addr", test_remove_addr, pm);
413427
l_test_add("set_limits", test_set_limits, pm);
414428
l_test_add("get_limits", test_get_limits, pm);
429+
l_test_add("set_flags", test_set_flags, pm);
415430
l_test_add("add_subflow", test_add_subflow, pm);
416431
l_test_add("set_backup", test_set_backup, pm);
417432
l_test_add("remove_subflow", test_remove_subflow, pm);

0 commit comments

Comments
 (0)