diff --git a/etc/mptcpd.conf.in b/etc/mptcpd.conf.in index e33ab4f9..19b2cdc8 100644 --- a/etc/mptcpd.conf.in +++ b/etc/mptcpd.conf.in @@ -37,6 +37,7 @@ path-manager=@mptcpd_default_pm@ # signal (do not use with the "fullmesh" flag) # backup # fullmesh (do not use with the "signal" flag) +# laminar # # Plugins that deal with the in-kernel path manager may use these # flags when advertising addresses. diff --git a/include/linux/mptcp_upstream.h b/include/linux/mptcp_upstream.h index 1284fd5e..a13655ca 100644 --- a/include/linux/mptcp_upstream.h +++ b/include/linux/mptcp_upstream.h @@ -31,19 +31,28 @@ #define MPTCP_INFO_FLAG_FALLBACK _BITUL(0) #define MPTCP_INFO_FLAG_REMOTE_KEY_RECEIVED _BITUL(1) -#define MPTCP_PM_ADDR_FLAG_SIGNAL (1 << 0) -#define MPTCP_PM_ADDR_FLAG_SUBFLOW (1 << 1) -#define MPTCP_PM_ADDR_FLAG_BACKUP (1 << 2) -#define MPTCP_PM_ADDR_FLAG_FULLMESH (1 << 3) -#define MPTCP_PM_ADDR_FLAG_IMPLICIT (1 << 4) +#define MPTCP_PM_EV_FLAG_DENY_JOIN_ID0 _BITUL(0) +#define MPTCP_PM_EV_FLAG_SERVER_SIDE _BITUL(1) + +#define MPTCP_PM_ADDR_FLAG_SIGNAL _BITUL(0) +#define MPTCP_PM_ADDR_FLAG_SUBFLOW _BITUL(1) +#define MPTCP_PM_ADDR_FLAG_BACKUP _BITUL(2) +#define MPTCP_PM_ADDR_FLAG_FULLMESH _BITUL(3) +#define MPTCP_PM_ADDR_FLAG_IMPLICIT _BITUL(4) +#define MPTCP_PM_ADDR_FLAG_LAMINAR _BITUL(5) struct mptcp_info { __u8 mptcpi_subflows; + #define mptcpi_extra_subflows mptcpi_subflows __u8 mptcpi_add_addr_signal; __u8 mptcpi_add_addr_accepted; __u8 mptcpi_subflows_max; + #define mptcpi_limit_extra_subflows mptcpi_subflows_max __u8 mptcpi_add_addr_signal_max; + #define mptcpi_endp_signal_max mptcpi_add_addr_signal_max __u8 mptcpi_add_addr_accepted_max; + #define mptcpi_limit_add_addr_accepted mptcpi_add_addr_accepted_max + /* 16-bit hole that can no longer be filled */ __u32 mptcpi_flags; __u32 mptcpi_token; __u64 mptcpi_write_seq; @@ -51,14 +60,17 @@ struct mptcp_info { __u64 mptcpi_rcv_nxt; __u8 mptcpi_local_addr_used; __u8 mptcpi_local_addr_max; + #define mptcpi_endp_subflow_max mptcpi_local_addr_max __u8 mptcpi_csum_enabled; + /* 8-bit hole that can no longer be filled */ __u32 mptcpi_retransmits; __u64 mptcpi_bytes_retrans; __u64 mptcpi_bytes_sent; __u64 mptcpi_bytes_received; __u64 mptcpi_bytes_acked; __u8 mptcpi_subflows_total; - __u8 reserved[3]; + __u8 mptcpi_endp_laminar_max; + __u8 reserved[2]; __u32 mptcpi_last_data_sent; __u32 mptcpi_last_data_recv; __u32 mptcpi_last_ack_recv; diff --git a/include/mptcpd/types.h b/include/mptcpd/types.h index ed16a810..56bba74d 100644 --- a/include/mptcpd/types.h +++ b/include/mptcpd/types.h @@ -73,6 +73,9 @@ typedef uint32_t mptcpd_flags_t; * @note Do not use with @c MPTCPD_ADDR_FLAG_SIGNAL. */ #define MPTCPD_ADDR_FLAG_FULLMESH (1U << 3) + +/// Use this endpoint in reaction to ADD_ADDR, but only once. +#define MPTCPD_ADDR_FLAG_LAMINAR (1U << 5) ///@} /** diff --git a/man/mptcpd.8.in b/man/mptcpd.8.in index 602f24c6..ba4224a6 100644 --- a/man/mptcpd.8.in +++ b/man/mptcpd.8.in @@ -72,8 +72,9 @@ is a comma separated list containing one or more of the flags .IR subflow , .IR signal , .IR backup , +.IR fullmesh , and -.I fullmesh +.IR laminar that plugins that deal with the in-kernel path manager may use when advertising addresses, e.g. .B --addr-flags=subflow diff --git a/plugins/path_managers/addr_adv.c b/plugins/path_managers/addr_adv.c index cfb66d4e..94f95019 100644 --- a/plugins/path_managers/addr_adv.c +++ b/plugins/path_managers/addr_adv.c @@ -54,7 +54,8 @@ static void update_limits(struct mptcpd_pm *pm, int delta) If the pm creates outgoing subflows, we assume this is the client side, and accepts add_addrs from the server. */ - if (pm->config->addr_flags & MPTCPD_ADDR_FLAG_SUBFLOW) + if (pm->config->addr_flags & + (MPTCPD_ADDR_FLAG_SUBFLOW | MPTCPD_ADDR_FLAG_LAMINAR)) _limits[1].limit = _limits[0].limit; int const result = mptcpd_kpm_set_limits(pm, diff --git a/src/configuration.c b/src/configuration.c index fc967a20..8394ebc9 100644 --- a/src/configuration.c +++ b/src/configuration.c @@ -121,6 +121,7 @@ static struct tok_entry const addr_flags_toks[] = { { MPTCPD_ADDR_FLAG_SIGNAL, "signal" }, { MPTCPD_ADDR_FLAG_BACKUP, "backup" }, { MPTCPD_ADDR_FLAG_FULLMESH, "fullmesh" }, + { MPTCPD_ADDR_FLAG_LAMINAR, "laminar" }, { 0, NULL }, }; diff --git a/src/netlink_pm_upstream.c b/src/netlink_pm_upstream.c index 4f43fae9..541a7242 100644 --- a/src/netlink_pm_upstream.c +++ b/src/netlink_pm_upstream.c @@ -34,7 +34,8 @@ #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 \ - || MPTCPD_ADDR_FLAG_FULLMESH != MPTCP_PM_ADDR_FLAG_FULLMESH + || MPTCPD_ADDR_FLAG_FULLMESH != MPTCP_PM_ADDR_FLAG_FULLMESH \ + || MPTCPD_ADDR_FLAG_LAMINAR != MPTCP_PM_ADDR_FLAG_LAMINAR # error Mismatch between mptcpd and upstream kernel addr flags. #endif diff --git a/tests/test-commands.c b/tests/test-commands.c index 6cad3b34..3203a72f 100644 --- a/tests/test-commands.c +++ b/tests/test-commands.c @@ -58,6 +58,9 @@ struct test_addr_info // MPTCP address ID used for add_addr and dump_addr calls. mptcpd_aid_t id; + + // MPTCP address flags used in the endpoints + mptcpd_flags_t const flags; }; struct test_info @@ -186,6 +189,7 @@ static void get_addr_callback(struct mptcpd_addr_info const *info, assert(mptcpd_addr_info_get_id(info) == k_addr->id); assert(mptcpd_addr_info_get_index(info) == k_addr->ifindex); + assert(mptcpd_addr_info_get_flags(info) == k_addr->flags); assert(sockaddr_is_equal(k_addr->addr, mptcpd_addr_info_get_addr(info))); } @@ -210,6 +214,7 @@ static void dump_addrs_callback(struct mptcpd_addr_info const *info, return; assert(mptcpd_addr_info_get_index(info) == k_addr->ifindex); + assert(mptcpd_addr_info_get_flags(info) == k_addr->flags); assert(sockaddr_is_equal(k_addr->addr, mptcpd_addr_info_get_addr(info))); } @@ -327,12 +332,10 @@ static void test_add_addr_kernel(void const *test_data) k_addr->id = mptcpd_idm_get_id(idm, k_addr->addr); - uint32_t flags = 0; - int const result = mptcpd_kpm_add_addr(pm, k_addr->addr, k_addr->id, - flags, + k_addr->flags, k_addr->ifindex); assert(result == 0 || result == ENOTSUP); @@ -911,7 +914,8 @@ static void test_commands(void const *data) .k_addr = { .addr = (struct sockaddr *) &kernel_addr, .ifindex = if_nametoindex(loopback), - .prefix_len = get_prefix_len(info.k_addr.addr) + .prefix_len = get_prefix_len(info.k_addr.addr), + .flags = MPTCPD_ADDR_FLAG_SUBFLOW } }; diff --git a/tests/test-configuration.c b/tests/test-configuration.c index 5623a3f0..d2508d36 100644 --- a/tests/test-configuration.c +++ b/tests/test-configuration.c @@ -108,6 +108,17 @@ static void test_load_plugins(void const *test_data) RUN_CONFIG(argv); } +static void test_addr_flags(void const *test_data) +{ + (void) test_data; + + static char *argv[] = + { TEST_PROGRAM_NAME, "--addr-flags", + "signal,subflow,fullmesh,backup,laminar" }; + + RUN_CONFIG(argv); +} + static void test_multi_arg(void const *test_data) { (void) test_data; @@ -176,6 +187,7 @@ int main(int argc, char *argv[]) l_test_add("plugin dir", test_plugin_dir, NULL); l_test_add("path manager", test_path_manager, NULL); l_test_add("load plugins", test_load_plugins, NULL); + l_test_add("addr flags", test_addr_flags, NULL); l_test_add("multi arg", test_multi_arg, NULL); l_test_add("config file", test_config_file, NULL); l_test_add("debug", test_debug, NULL);