diff options
author | Simon Lin <simonlin@google.com> | 2022-07-27 11:34:07 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-26 20:34:07 -0700 |
commit | fe3f8f4c67eac17207df1e887e0adf7d497dd6f3 (patch) | |
tree | e6b2724218f3a5de3359cccb74bb92af4653049c /src/agent | |
parent | c70d2a03536366fddf4babdbf4cd6ad7a315d151 (diff) | |
download | ot-br-posix-fe3f8f4c67eac17207df1e887e0adf7d497dd6f3.tar.gz |
[infra-netif] select infrastructure link among multiple candidates (#1353)
This commit implements a general Infrastructure Link Selection that
allows otbr-agent to select one network interface among multiple
network interface candidates (specified by multiple `-B` arguments) as
the infrastructure link.
The Infrastructure Link Selection uses following rules:
- The network link in the most usable state is selected
- Prefer `up and running` to `up`
- Prefer `up` to `down`
- Prefer `down` to `invalid`
- Once an interface is selected, it's preferred if either is true:
- The interface is still `up and running`
- No other interface is `up and running`
- The interface has been `up and running` within last 10 seconds
`otbr-agent` uses Infrastructure Link Selection to select the correct
infrastructure link:
- Run Infrastructure Link Selection when started to select the
infrastructure link
- Run Infrastructure Link Selection when network interface states
change is detected. otbr-agent would quit if a different
infrastructure link is selected, expecting the system to restart it
to use the new infrastructure link.
Note:
- The Infrastructure Link Selection mechanism is effectively disabled
if less than two infrastructure link names are specified.
- The current implementation only works for Linux platforms.
Diffstat (limited to 'src/agent')
-rw-r--r-- | src/agent/application.cpp | 28 | ||||
-rw-r--r-- | src/agent/application.hpp | 10 | ||||
-rw-r--r-- | src/agent/main.cpp | 25 |
3 files changed, 45 insertions, 18 deletions
diff --git a/src/agent/application.cpp b/src/agent/application.cpp index 1ddd4741..eed641e3 100644 --- a/src/agent/application.cpp +++ b/src/agent/application.cpp @@ -40,6 +40,7 @@ #include "agent/application.hpp" #include "common/code_utils.hpp" #include "common/mainloop_manager.hpp" +#include "utils/infra_link_selector.hpp" namespace otbr { @@ -47,17 +48,22 @@ std::atomic_bool Application::sShouldTerminate(false); const struct timeval Application::kPollTimeout = {10, 0}; Application::Application(const std::string & aInterfaceName, - const std::string & aBackboneInterfaceName, + const std::vector<const char *> &aBackboneInterfaceNames, const std::vector<const char *> &aRadioUrls, bool aEnableAutoAttach) : mInterfaceName(aInterfaceName) - , mBackboneInterfaceName(aBackboneInterfaceName) - , mNcp(mInterfaceName.c_str(), aRadioUrls, mBackboneInterfaceName.c_str(), /* aDryRun */ false, aEnableAutoAttach) +#if __linux__ + , mInfraLinkSelector(aBackboneInterfaceNames) + , mBackboneInterfaceName(mInfraLinkSelector.Select()) +#else + , mBackboneInterfaceName(aBackboneInterfaceNames.empty() ? "" : aBackboneInterfaceNames.front()) +#endif + , mNcp(mInterfaceName.c_str(), aRadioUrls, mBackboneInterfaceName, /* aDryRun */ false, aEnableAutoAttach) #if OTBR_ENABLE_BORDER_AGENT , mBorderAgent(mNcp) #endif #if OTBR_ENABLE_BACKBONE_ROUTER - , mBackboneAgent(mNcp, aInterfaceName, aBackboneInterfaceName) + , mBackboneAgent(mNcp, aInterfaceName, mBackboneInterfaceName) #endif #if OTBR_ENABLE_OPENWRT , mUbusAgent(mNcp) @@ -111,7 +117,7 @@ otbrError Application::Run(void) { otbrError error = OTBR_ERROR_NONE; - otbrLogInfo("Border router agent started."); + otbrLogInfo("Thread Border Router started on AIL %s.", mBackboneInterfaceName); #ifdef HAVE_LIBSYSTEMD if (getenv("SYSTEMD_EXEC_PID") != nullptr) @@ -158,6 +164,18 @@ otbrError Application::Run(void) if (rval >= 0) { MainloopManager::GetInstance().Process(mainloop); + +#if __linux__ + { + const char *newInfraLink = mInfraLinkSelector.Select(); + + if (mBackboneInterfaceName != newInfraLink) + { + error = OTBR_ERROR_INFRA_LINK_CHANGED; + break; + } + } +#endif } else if (errno != EINTR) { diff --git a/src/agent/application.hpp b/src/agent/application.hpp index 185b6a88..d12ed154 100644 --- a/src/agent/application.hpp +++ b/src/agent/application.hpp @@ -58,6 +58,7 @@ #if OTBR_ENABLE_VENDOR_SERVER #include "agent/vendor.hpp" #endif +#include "utils/infra_link_selector.hpp" namespace otbr { @@ -87,7 +88,7 @@ public: * */ explicit Application(const std::string & aInterfaceName, - const std::string & aBackboneInterfaceName, + const std::vector<const char *> &aBackboneInterfaceNames, const std::vector<const char *> &aRadioUrls, bool aEnableAutoAttach); @@ -118,8 +119,11 @@ private: static void HandleSignal(int aSignal); - std::string mInterfaceName; - std::string mBackboneInterfaceName; + std::string mInterfaceName; +#if __linux__ + otbr::Utils::InfraLinkSelector mInfraLinkSelector; +#endif + const char * mBackboneInterfaceName; Ncp::ControllerOpenThread mNcp; #if OTBR_ENABLE_BORDER_AGENT BorderAgent mBorderAgent; diff --git a/src/agent/main.cpp b/src/agent/main.cpp index 39a8a8d6..14c33cba 100644 --- a/src/agent/main.cpp +++ b/src/agent/main.cpp @@ -37,13 +37,13 @@ #include <string> #include <vector> +#include <assert.h> #include <getopt.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> -#include <assert.h> #include <openthread/logging.h> #include <openthread/platform/radio.h> @@ -184,13 +184,13 @@ static int realmain(int argc, char *argv[]) { otbrLogLevel logLevel = GetDefaultLogLevel(); int opt; - int ret = EXIT_SUCCESS; - const char * interfaceName = kDefaultInterfaceName; - const char * backboneInterfaceName = ""; - bool verbose = false; - bool printRadioVersion = false; - bool enableAutoAttach = true; + int ret = EXIT_SUCCESS; + const char * interfaceName = kDefaultInterfaceName; + bool verbose = false; + bool printRadioVersion = false; + bool enableAutoAttach = true; std::vector<const char *> radioUrls; + std::vector<const char *> backboneInterfaceNames; long parseResult; std::set_new_handler(OnAllocateFailed); @@ -200,7 +200,8 @@ static int realmain(int argc, char *argv[]) switch (opt) { case OTBR_OPT_BACKBONE_INTERFACE_NAME: - backboneInterfaceName = optarg; + backboneInterfaceNames.push_back(optarg); + otbrLogNotice("Backbone interface: %s", optarg); break; case OTBR_OPT_DEBUG_LEVEL: @@ -254,7 +255,11 @@ static int realmain(int argc, char *argv[]) otbrLogNotice("Running %s", OTBR_PACKAGE_VERSION); otbrLogNotice("Thread version: %s", otbr::Ncp::ControllerOpenThread::GetThreadVersion()); otbrLogNotice("Thread interface: %s", interfaceName); - otbrLogNotice("Backbone interface: %s", backboneInterfaceName); + + if (backboneInterfaceNames.empty()) + { + otbrLogNotice("Backbone interface is not specified"); + } for (int i = optind; i < argc; i++) { @@ -269,7 +274,7 @@ static int realmain(int argc, char *argv[]) } { - otbr::Application app(interfaceName, backboneInterfaceName, radioUrls, enableAutoAttach); + otbr::Application app(interfaceName, backboneInterfaceNames, radioUrls, enableAutoAttach); gApp = &app; app.Init(); |