aboutsummaryrefslogtreecommitdiff
path: root/src/agent
diff options
context:
space:
mode:
authorSimon Lin <simonlin@google.com>2022-07-27 11:34:07 +0800
committerGitHub <noreply@github.com>2022-07-26 20:34:07 -0700
commitfe3f8f4c67eac17207df1e887e0adf7d497dd6f3 (patch)
treee6b2724218f3a5de3359cccb74bb92af4653049c /src/agent
parentc70d2a03536366fddf4babdbf4cd6ad7a315d151 (diff)
downloadot-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.cpp28
-rw-r--r--src/agent/application.hpp10
-rw-r--r--src/agent/main.cpp25
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();