From 567afaac29d9bc0cc78bc193d4fc235d4a4a93f7 Mon Sep 17 00:00:00 2001 From: Ossama Othman Date: Mon, 10 Jan 2022 22:05:33 -0800 Subject: [PATCH] Support only one kernel at run-time, (#156) Support only one MPTCP capable kernel at run-time, either the upstream or multipath-tcp.org kernel but not both. This simplifies the kernel support in mptcpd, and further prepares mptcpd to support the upcoming user space MPTCP path management commands in the upstream kernel. * src: Add user space PM command stubs for upstream. * configure: Add '--with-kernel' option. Allow the user to choose build-time support for either the upstream or multipath-tcp.org kernel, e.g.: ./configure --with-kernel=multipath-tcp.org Valid kernel options are "upstream" or "multipath-tcp.org", with the former being the default. Mptcpd will no longer support both kernels at run-time. * github: Add multipath-tcp.org kernel build. --- .github/workflows/multipath-tcp.org.yml | 31 +++++++ configure.ac | 113 +++++++++++++++--------- include/linux/mptcp_upstream.h | 4 + include/mptcpd/private/mptcp_upstream.h | 3 +- include/mptcpd/private/netlink_pm.h | 3 + include/mptcpd/private/path_manager.h | 46 +++++++--- m4/mptcpd_kernel.m4 | 37 ++++++++ src/Makefile.am | 8 +- src/netlink_pm.c | 55 +----------- src/netlink_pm.h | 30 +++++++ src/netlink_pm_mptcp_org.c | 13 ++- src/netlink_pm_upstream.c | 100 ++++++++++++++++++++- src/path_manager.c | 26 +++--- 13 files changed, 339 insertions(+), 130 deletions(-) create mode 100644 .github/workflows/multipath-tcp.org.yml create mode 100644 m4/mptcpd_kernel.m4 diff --git a/.github/workflows/multipath-tcp.org.yml b/.github/workflows/multipath-tcp.org.yml new file mode 100644 index 00000000..0377dab0 --- /dev/null +++ b/.github/workflows/multipath-tcp.org.yml @@ -0,0 +1,31 @@ +name: multipath-tcp.org kernel + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: dependencies + run: sudo apt-get -y install autoconf-archive git + - name: build and install ELL + run: | + git clone git://git.kernel.org/pub/scm/libs/ell/ell.git + cd ell + git checkout 0.30 + ./bootstrap + ./configure --prefix=/usr + sudo make install + - name: bootstrap + run: ./bootstrap + - name: configure + run: ./configure --with-kernel=multipath-tcp.org + - name: make + run: make diff --git a/configure.ac b/configure.ac index 17d428f1..8dcd67ba 100644 --- a/configure.ac +++ b/configure.ac @@ -108,6 +108,19 @@ AC_DEFINE_UNQUOTED([MPTCPD_LOGGER], [Log message destination.]) AC_SUBST([mptcpd_logger],[$enable_logging]) +# Allow the user to choose support for either the upstream or +# multipath-tcp.org kernel. +AC_ARG_WITH([kernel], + [AS_HELP_STRING([--with-kernel[=KERNEL]], + [Support a specific MPTCP capable kernel + (upstream, multipath-tcp.org, auto) + @<:@default=auto@:>@])], + [AS_CASE([$withval], + [upstream | multipath-tcp.org | auto], + [with_kernel=$withval], + [AC_MSG_ERROR([invalid MPTCP capable kernel: $withval])])], + [with_kernel=auto]) + # Allow the user to set the default path manager plugin at 'configure-time'. AC_ARG_WITH([path-manager], [AS_HELP_STRING([--with-path-manager[=PLUGIN]], @@ -200,29 +213,41 @@ AH_TEMPLATE([HAVE_LINUX_MPTCP_H_UPSTREAM], AH_TEMPLATE([HAVE_LINUX_MPTCP_H_MPTCP_ORG], [Define to 1 if you have the multipath-tcp.org kernel header.]) -AH_TEMPLATE([HAVE_LINUX_MPTCP_H_UPSTREAM_EVENTS], - [Define to 1 if supports MPTCP genl events.]) AC_CHECK_HEADERS([linux/mptcp.h], - [ - AX_CHECK_DEFINE( - [linux/mptcp.h], - [MPTCP_PM_NAME], - [AC_DEFINE([HAVE_LINUX_MPTCP_H_UPSTREAM], [1]) - AX_CHECK_DEFINE([linux/mptcp.h], - [MPTCP_PM_EV_GRP_NAME], - [AC_DEFINE([HAVE_LINUX_MPTCP_H_UPSTREAM_EVENTS], - [1]) - ]) + [ + MPTCPD_IF_UPSTREAM_KERNEL( + [ + AC_DEFINE([HAVE_LINUX_MPTCP_H_UPSTREAM], [1]) + AS_IF([test "x$with_kernel" = "xauto"], + [with_kernel=upstream]) + ], + [ + MPTCPD_IF_MPTCP_ORG_KERNEL( + [ + AC_DEFINE([HAVE_LINUX_MPTCP_H_MPTCP_ORG], [1]) + AS_IF([test "x$with_kernel" = "xauto"], + [with_kernel=multipath-tcp.org]) ], [ - AX_CHECK_DEFINE( - [linux/mptcp.h], - [MPTCP_GENL_NAME], - [AC_DEFINE([HAVE_LINUX_MPTCP_H_MPTCP_ORG], [1])], - [AC_MSG_ERROR([Discrepancy in .])]) + AC_MSG_WARN([Unsupported header. Using fallback.]) ]) - ], - [AC_MSG_WARN([ header not found. Using fallback.])]) + ]) + ], + [ + AC_MSG_WARN([ header not found. Using fallback.]) + ]) + +AS_IF([test "x$with_kernel" = "xauto"], [with_kernel=upstream]) + +AM_CONDITIONAL([HAVE_UPSTREAM_KERNEL], + [test "x$with_kernel" = "xupstream"]) + +AH_TEMPLATE([HAVE_UPSTREAM_KERNEL], + [Define to 1 if mptcpd should support the upstream kernel.]) +AS_IF([test "x$with_kernel" = "xupstream"], + [AC_DEFINE([HAVE_UPSTREAM_KERNEL]) + AC_MSG_NOTICE([Building support for upstream kernel.])], + [AC_MSG_NOTICE([Building support for multipath-tcp.org kernel.])]) # --------------------------------------------------------------- # Checks for typedefs, structures, and compiler characteristics. @@ -249,14 +274,14 @@ LIBS="$LIBS $ELL_LIBS" dnl l_genl_msg_get_extended_error() was introduced in ELL v0.31. AC_CHECK_FUNC([l_genl_msg_get_extended_error], [AC_DEFINE([HAVE_L_GENL_MSG_GET_EXTENDED_ERROR], - [], - [ELL has l_genl_msg_get_extended_error()])]) + [], + [ELL has l_genl_msg_get_extended_error()])]) dnl l_hashmap_replace() was introduced in ELL v0.33. AC_CHECK_FUNC([l_hashmap_replace], [AC_DEFINE([HAVE_L_HASHMAP_REPLACE], - [], - [ELL has l_hashmap_replace()])]) + [], + [ELL has l_hashmap_replace()])]) LIBS=$mptcpd_save_libs # --------------------------------------------------------------- @@ -272,29 +297,29 @@ AX_APPEND_COMPILE_FLAGS([-Wextra -Werror -pedantic]) # --------------------------------------------------------------- AC_ARG_ENABLE(stack-protection, - [AS_HELP_STRING([--disable-stack-protection], - [Disable compiler stack protection. - FORTIFY_SOURCE=2 and -fstack-protector-strong] - )], - [], - [enable_stack_protection=yes]) + [AS_HELP_STRING([--disable-stack-protection], + [Disable compiler stack protection. + FORTIFY_SOURCE=2 and -fstack-protector-strong] + )], + [], + [enable_stack_protection=yes]) AS_IF([test "x$enable_stack_protection" = "xyes"], - [ - # Fortify source - # Enabling optimization implies _FORTIFY_SOURCE on some platforms. - # Explicitly redefine to _FORTIFY_SOURCE=2 to make sure we have the - # desired fortification level. - AX_APPEND_FLAG([-U_FORTIFY_SOURCE], [CPPFLAGS]) - AX_APPEND_FLAG([-D_FORTIFY_SOURCE=2], [CPPFLAGS]) - - # Stack-based buffer overrun detection - MPTCPD_ADD_COMPILE_FLAG([-fstack-protector-strong], - [# GCC < 4.9 - MPTCPD_ADD_COMPILE_FLAG([-fstack-protector]) - ]) - ],[] - ) + [ + # Fortify source + # Enabling optimization implies _FORTIFY_SOURCE on some platforms. + # Explicitly redefine to _FORTIFY_SOURCE=2 to make sure we have the + # desired fortification level. + AX_APPEND_FLAG([-U_FORTIFY_SOURCE], [CPPFLAGS]) + AX_APPEND_FLAG([-D_FORTIFY_SOURCE=2], [CPPFLAGS]) + + # Stack-based buffer overrun detection + MPTCPD_ADD_COMPILE_FLAG([-fstack-protector-strong], + [# GCC < 4.9 + MPTCPD_ADD_COMPILE_FLAG([-fstack-protector]) + ]) + ],[] + ) # Format string vulnerabilities # -Wformat=2 implies: diff --git a/include/linux/mptcp_upstream.h b/include/linux/mptcp_upstream.h index 7b05f710..8e9c3d6c 100644 --- a/include/linux/mptcp_upstream.h +++ b/include/linux/mptcp_upstream.h @@ -48,6 +48,8 @@ enum { MPTCP_PM_ATTR_ADDR, /* nested address */ MPTCP_PM_ATTR_RCV_ADD_ADDRS, /* u32 */ MPTCP_PM_ATTR_SUBFLOWS, /* u32 */ + MPTCP_PM_ATTR_TOKEN, /* u32 */ + MPTCP_PM_ATTR_LOC_ID, /* u8 */ __MPTCP_PM_ATTR_MAX }; @@ -84,6 +86,8 @@ enum { MPTCP_PM_CMD_SET_LIMITS, MPTCP_PM_CMD_GET_LIMITS, MPTCP_PM_CMD_SET_FLAGS, + MPTCP_PM_CMD_ANNOUNCE, + MPTCP_PM_CMD_REMOVE, __MPTCP_PM_CMD_AFTER_LAST }; diff --git a/include/mptcpd/private/mptcp_upstream.h b/include/mptcpd/private/mptcp_upstream.h index 0a3ffd26..707d0e23 100644 --- a/include/mptcpd/private/mptcp_upstream.h +++ b/include/mptcpd/private/mptcp_upstream.h @@ -16,8 +16,7 @@ # include "mptcpd/private/config.h" #endif -#if defined(HAVE_LINUX_MPTCP_H_UPSTREAM) \ - && defined(HAVE_LINUX_MPTCP_H_UPSTREAM_EVENTS) +#ifdef HAVE_LINUX_MPTCP_H_UPSTREAM # include #else /* diff --git a/include/mptcpd/private/netlink_pm.h b/include/mptcpd/private/netlink_pm.h index 57d85e0f..22fa44ef 100644 --- a/include/mptcpd/private/netlink_pm.h +++ b/include/mptcpd/private/netlink_pm.h @@ -15,6 +15,9 @@ extern "C" { #endif +struct mptcpd_pm_cmd_ops; +struct mptcpd_kpm_cmd_ops; + /** * @struct mptcpd_netlink_pm * diff --git a/include/mptcpd/private/path_manager.h b/include/mptcpd/private/path_manager.h index f11a760c..da2ae6e7 100644 --- a/include/mptcpd/private/path_manager.h +++ b/include/mptcpd/private/path_manager.h @@ -134,6 +134,9 @@ struct mptcpd_pm_cmd_ops * ignored if it is zero. * @param[in] id MPTCP local address ID. * @param[in] token MPTCP connection token. + * + * @return @c 0 if operation was successful. -1 or @c errno + * otherwise. */ int (*add_addr)(struct mptcpd_pm *pm, struct sockaddr const *addr, @@ -142,6 +145,12 @@ struct mptcpd_pm_cmd_ops /** * @brief Stop advertising network address to peers. + * @param[in] pm The mptcpd path manager object. + * @param[in] address_id MPTCP local address ID. + * @param[in] token MPTCP connection token. + * + * @return @c 0 if operation was successful. -1 or @c errno + * otherwise. */ int (*remove_addr)(struct mptcpd_pm *pm, mptcpd_aid_t address_id, @@ -177,12 +186,12 @@ struct mptcpd_pm_cmd_ops /** * @brief Remove a subflow. * - * @param[in] pm The mptcpd path manager object. - * @param[in] token MPTCP connection token. - * @param[in] local_addr MPTCP subflow local address - * information, including the port. - * @param[in] remote_addr MPTCP subflow remote address - * information, including the port. + * @param[in] pm The mptcpd path manager object. + * @param[in] token MPTCP connection token. + * @param[in] local_addr MPTCP subflow local address + * information, including the port. + * @param[in] remote_addr MPTCP subflow remote address + * information, including the port. * * @return @c 0 if operation was successful. @c errno * otherwise. @@ -195,14 +204,14 @@ struct mptcpd_pm_cmd_ops /** * @brief Set priority of a subflow. * - * @param[in] pm The mptcpd path manager object. - * @param[in] token MPTCP connection token. - * @param[in] local_addr MPTCP subflow local address - * information, including the port. - * @param[in] remote_addr MPTCP subflow remote address - * information, including the port. - * @param[in] backup Whether or not to set the MPTCP - * subflow backup priority flag. + * @param[in] pm The mptcpd path manager object. + * @param[in] token MPTCP connection token. + * @param[in] local_addr MPTCP subflow local address + * information, including the port. + * @param[in] remote_addr MPTCP subflow remote address + * information, including the port. + * @param[in] backup Whether or not to set the MPTCP + * subflow backup priority flag. * * @return @c 0 if operation was successful. @c errno * otherwise. @@ -238,6 +247,9 @@ struct mptcpd_kpm_cmd_ops * @param[in] id MPTCP local address ID. * @param[in] flags * @param[in] index Network interface index (optional). + * + * @return @c 0 if operation was successful. -1 or @c errno + * otherwise. */ int (*add_addr)(struct mptcpd_pm *pm, struct sockaddr const *addr, @@ -247,6 +259,12 @@ struct mptcpd_kpm_cmd_ops /** * @brief Stop advertising network address to peers. + * + * @param[in] pm The mptcpd path manager object. + * @param[in] address_id MPTCP local address ID. + * + * @return @c 0 if operation was successful. -1 or @c errno + * otherwise. */ int (*remove_addr)(struct mptcpd_pm *pm, mptcpd_aid_t address_id); diff --git a/m4/mptcpd_kernel.m4 b/m4/mptcpd_kernel.m4 new file mode 100644 index 00000000..ff783aa5 --- /dev/null +++ b/m4/mptcpd_kernel.m4 @@ -0,0 +1,37 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2021, Intel Corporation + +#serial 1 + +# MPTCPD_IF_UPSTREAM_KERNEL([ACTION-IF-TRUE], [ACTION-IF-FALSE]) +# +# Check if the header for the upstream kernel is +# available in the system include path. +AC_DEFUN([MPTCPD_IF_UPSTREAM_KERNEL], +[ + AC_CACHE_CHECK([for MPTCP_PM_CMD_ANNOUNCE in linux/mptcp.h], + [mptcpd_cv_header_upstream], + [ + AC_COMPILE_IFELSE([ + AC_LANG_SOURCE([ +#include + +int announce_cmd(void) { return MPTCP_PM_CMD_ANNOUNCE; } + ]) + ], + [mptcpd_cv_header_upstream=yes], + [mptcpd_cv_header_upstream=no]) + ]) + + AS_IF([test "x$mptcpd_cv_header_upstream" = xyes], [$1], [$2]) +]) + +# MPTCPD_IF_MPTCP_ORG_KERNEL([ACTION-IF-TRUE], [ACTION-IF-FALSE]) +# +# Check if the header for the multipath-tcp.org kernel +# is available in the system include path. +AC_DEFUN([MPTCPD_IF_MPTCP_ORG_KERNEL], +[ + AX_CHECK_DEFINE([linux/mptcp.h], [MPTCP_GENL_NAME], [$1], [$2]) +]) diff --git a/src/Makefile.am b/src/Makefile.am index 81cafe5d..93212cff 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,11 +19,15 @@ libpath_manager_la_SOURCES = \ configuration.c \ netlink_pm.c \ netlink_pm.h \ - netlink_pm_mptcp_org.c \ - netlink_pm_upstream.c \ path_manager.c \ path_manager.h +if HAVE_UPSTREAM_KERNEL +libpath_manager_la_SOURCES += netlink_pm_upstream.c +else +libpath_manager_la_SOURCES += netlink_pm_mptcp_org.c +endif + libpath_manager_la_LIBADD = \ $(top_builddir)/lib/libmptcpd.la \ $(ELL_LIBS) $(CODE_COVERAGE_LIBS) diff --git a/src/netlink_pm.c b/src/netlink_pm.c index a8a80451..b24dcc53 100644 --- a/src/netlink_pm.c +++ b/src/netlink_pm.c @@ -15,27 +15,10 @@ #include "netlink_pm.h" -/// Directory containing MPTCP sysctl variable entries. -#define MPTCP_SYSCTL_BASE "/proc/sys/net/mptcp/" -/// Constuct full path for MPTCP sysctl variable "@a name". -#define MPTCP_SYSCTL_VARIABLE(name) MPTCP_SYSCTL_BASE #name - -/// Get multipath-tcp.org kernel generic netlink PM characteristics. -struct mptcpd_netlink_pm const *mptcpd_get_netlink_pm_mptcp_org(void); - -/// Get upstream kernel generic netlink PM characteristics. -struct mptcpd_netlink_pm const *mptcpd_get_netlink_pm_upstream(void); - -/** - * @brief Verify that MPTCP is enabled at run-time in the kernel. - * - * Check that MPTCP is enabled through the specified @c sysctl - * variable. - */ -static bool check_kernel_mptcp_enabled(char const *path, - char const *variable, - int enable_val) +bool mptcpd_is_kernel_mptcp_enabled(char const *path, + char const *variable, + int enable_val) { FILE *const f = fopen(path, "r"); @@ -71,38 +54,6 @@ static bool check_kernel_mptcp_enabled(char const *path, return enabled; } -/// Are we being run under a MPTCP-capable upstream kernel? -static bool is_upstream_kernel(void) -{ - static char const path[] = MPTCP_SYSCTL_VARIABLE(enabled); - static char const name[] = "enabled"; - static int const enable_val = 1; - - return check_kernel_mptcp_enabled(path, name, enable_val); -} - -/// Are we being run under a MPTCP-capable multipath-tcp.org kernel? -static bool is_mptcp_org_kernel(void) -{ - static char const path[] = MPTCP_SYSCTL_VARIABLE(mptcp_enabled); - static char const name[] = "mptcp_enabled"; - static int const enable_val = 2; // or 1 - - return check_kernel_mptcp_enabled(path, name, enable_val); -} - -struct mptcpd_netlink_pm const *mptcpd_get_netlink_pm(void) -{ - if (is_upstream_kernel()) { - return mptcpd_get_netlink_pm_upstream(); - } else if (is_mptcp_org_kernel()) { - return mptcpd_get_netlink_pm_mptcp_org(); - } else { - return NULL; - } -} - - /* Local Variables: c-file-style: "linux" diff --git a/src/netlink_pm.h b/src/netlink_pm.h index 39bc58a2..9e064007 100644 --- a/src/netlink_pm.h +++ b/src/netlink_pm.h @@ -12,10 +12,40 @@ #include +#include + +#include + +/// Directory containing MPTCP sysctl variable entries. +#define MPTCP_SYSCTL_BASE "/proc/sys/net/mptcp/" + +/// Constuct full path for MPTCP sysctl variable "@a name". +#define MPTCP_SYSCTL_VARIABLE(name) MPTCP_SYSCTL_BASE #name + +struct sockaddr; +struct mptcpd_pm; /// Get MPTCP generic netlink path manager characteristics. struct mptcpd_netlink_pm const *mptcpd_get_netlink_pm(void); +/** + * @brief Verify that MPTCP is enabled at run-time in the kernel. + * + * Check that MPTCP is enabled through the specified @c sysctl + * variable. + * + * @param[in] path Path to file containing MPTCP sysctl "enable" + * value, e.g. "/proc/sys/net/mptcp/enabled". + * @param[in] variable Name of "enabled" variable. + * @param[in] enable_val Value needed to enable MPTCP in the kernel. + * + * @return @c true if MPTCP is enabled in the kernel, and @c false + * otherwise. + */ +bool mptcpd_is_kernel_mptcp_enabled(char const *path, + char const *variable, + int enable_val); + #endif /* MPTCPD_NETLINK_PM_H */ diff --git a/src/netlink_pm_mptcp_org.c b/src/netlink_pm_mptcp_org.c index 4a6dd7a0..ebaaa348 100644 --- a/src/netlink_pm_mptcp_org.c +++ b/src/netlink_pm_mptcp_org.c @@ -20,6 +20,7 @@ #include #include "commands.h" +#include "netlink_pm.h" #include #include @@ -546,8 +547,18 @@ static struct mptcpd_netlink_pm const npm = { .cmd_ops = &cmd_ops }; -struct mptcpd_netlink_pm const *mptcpd_get_netlink_pm_mptcp_org(void) +struct mptcpd_netlink_pm const *mptcpd_get_netlink_pm(void) { + l_debug(PACKAGE " was built with support for the " + "multipath-tcp.org kernel."); + + static char const path[] = MPTCP_SYSCTL_VARIABLE(mptcp_enabled); + static char const name[] = "mptcp_enabled"; + static int const enable_val = 2; // or 1 + + if (!mptcpd_is_kernel_mptcp_enabled(path, name, enable_val)) + return NULL; + check_kernel_mptcp_path_manager(); return &npm; diff --git a/src/netlink_pm_upstream.c b/src/netlink_pm_upstream.c index f274107b..9e4adadc 100644 --- a/src/netlink_pm_upstream.c +++ b/src/netlink_pm_upstream.c @@ -28,6 +28,7 @@ #include #include "commands.h" +#include "netlink_pm.h" #include "path_manager.h" // Sanity check @@ -37,6 +38,80 @@ # error Mismatch between mptcpd and upstream kernel addr flags. #endif + +static int upstream_cmd_announce(struct mptcpd_pm *pm, + struct sockaddr const *addr, + mptcpd_aid_t id, + mptcpd_token_t token) +{ + (void) pm; + (void) addr; + (void) id; + (void) token; + + return ENOTSUP; +} + +static int upstream_cmd_remove(struct mptcpd_pm *pm, + mptcpd_aid_t address_id, + mptcpd_token_t token) +{ + (void) pm; + (void) address_id; + (void) token; + + return ENOTSUP; +} + +static int upstream_add_subflow(struct mptcpd_pm *pm, + mptcpd_token_t token, + mptcpd_aid_t local_address_id, + mptcpd_aid_t remote_address_id, + struct sockaddr const *local_addr, + struct sockaddr const *remote_addr, + bool backup) +{ + (void) pm; + (void) token; + (void) local_address_id; + (void) remote_address_id; + (void) local_addr; + (void) remote_addr; + (void) backup; + + return ENOTSUP; +} + +static int upstream_remove_subflow(struct mptcpd_pm *pm, + mptcpd_token_t token, + struct sockaddr const *local_addr, + struct sockaddr const *remote_addr) +{ + (void) pm; + (void) token; + (void) local_addr; + (void) remote_addr; + + return ENOTSUP; +} + +static int upstream_set_backup(struct mptcpd_pm *pm, + mptcpd_token_t token, + struct sockaddr const *local_addr, + struct sockaddr const *remote_addr, + bool backup) +{ + (void) pm; + (void) token; + (void) local_addr; + (void) remote_addr; + (void) backup; + + return ENOTSUP; +} + +// -------------------------------------------------------------- + /** * @struct get_addr_user_callback * @@ -704,7 +779,18 @@ static int upstream_set_flags(struct mptcpd_pm *pm, NULL /* destroy */) == 0; } -static struct mptcpd_kpm_cmd_ops const cmd_ops = +// --------------------------------------------------------------------- + +static struct mptcpd_pm_cmd_ops const cmd_ops = +{ + .add_addr = upstream_cmd_announce, + .remove_addr = upstream_cmd_remove, + .add_subflow = upstream_add_subflow, + .remove_subflow = upstream_remove_subflow, + .set_backup = upstream_set_backup, +}; + +static struct mptcpd_kpm_cmd_ops const kcmd_ops = { .add_addr = upstream_add_addr, .remove_addr = upstream_remove_addr, @@ -719,11 +805,19 @@ static struct mptcpd_kpm_cmd_ops const cmd_ops = static struct mptcpd_netlink_pm const npm = { .name = MPTCP_PM_NAME, .group = MPTCP_PM_EV_GRP_NAME, - .kcmd_ops = &cmd_ops + .cmd_ops = &cmd_ops, + .kcmd_ops = &kcmd_ops }; -struct mptcpd_netlink_pm const *mptcpd_get_netlink_pm_upstream(void) +struct mptcpd_netlink_pm const *mptcpd_get_netlink_pm(void) { + static char const path[] = MPTCP_SYSCTL_VARIABLE(enabled); + static char const name[] = "enabled"; + static int const enable_val = 1; + + if (!mptcpd_is_kernel_mptcp_enabled(path, name, enable_val)) + return NULL; + return &npm; } diff --git a/src/path_manager.c b/src/path_manager.c index dc317fbe..5ccd849d 100644 --- a/src/path_manager.c +++ b/src/path_manager.c @@ -755,6 +755,7 @@ static void handle_mptcp_event(struct l_genl_msg *msg, void *user_data) }; } +#ifdef HAVE_UPSTREAM_KERNEL static void dump_addrs_callback(struct mptcpd_addr_info const *info, void *callback_data) { @@ -791,6 +792,7 @@ static void dump_addrs_callback(struct mptcpd_addr_info const *info, else l_error("ID sync failed: %u | %s", info->id, addrstr); } +#endif // HAVE_UPSTREAM_KERNEL static void notify_pm_ready(void *data, void *user_data) { @@ -903,25 +905,25 @@ static void family_appeared(struct l_genl_family_info const *info, pm->family = l_genl_family_new(pm->genl, name); +#ifdef HAVE_UPSTREAM_KERNEL /* MPTCP address IDs may already be assigned prior to mptcpd start by other applications or previous runs of mptcpd. Synchronize mptcpd address ID manager with address IDs maintained by the kernel. */ - if (pm->netlink_pm->kcmd_ops != NULL) { - if (pm->netlink_pm->kcmd_ops->dump_addrs != NULL - && pm->netlink_pm->kcmd_ops->dump_addrs( - pm, - dump_addrs_callback, - pm, - complete_pm_init) != 0) + if (pm->netlink_pm->kcmd_ops->dump_addrs(pm, + dump_addrs_callback, + pm, + complete_pm_init) != 0) l_error("Unable to synchronize ID manager with kernel."); - } else { - // In-kernel path manager commands are unimplemented. - // Complete initialization immediately. - complete_pm_init(pm); - } +#else + /* + In-kernel path manager commands are unimplemented. + Complete initialization immediately. + */ + complete_pm_init(pm); +#endif // HAVE_UPSTREAM_KERNEL /** * @todo Register a callback once the kernel MPTCP path