[netif-posix] add an option to persistent interface (#8033)

This commit is contained in:
Zang MingJie
2022-10-24 14:57:48 -07:00
committed by GitHub
parent d1653a8edc
commit e4bf2ffe34
5 changed files with 59 additions and 30 deletions
+10 -3
View File
@@ -141,6 +141,7 @@ enum
OT_POSIX_OPT_DRY_RUN = 'n', OT_POSIX_OPT_DRY_RUN = 'n',
OT_POSIX_OPT_HELP = 'h', OT_POSIX_OPT_HELP = 'h',
OT_POSIX_OPT_INTERFACE_NAME = 'I', OT_POSIX_OPT_INTERFACE_NAME = 'I',
OT_POSIX_OPT_PERSISTENT_INTERFACE = 'p',
OT_POSIX_OPT_TIME_SPEED = 's', OT_POSIX_OPT_TIME_SPEED = 's',
OT_POSIX_OPT_VERBOSE = 'v', OT_POSIX_OPT_VERBOSE = 'v',
@@ -156,6 +157,7 @@ static const struct option kOptions[] = {
{"dry-run", no_argument, NULL, OT_POSIX_OPT_DRY_RUN}, {"dry-run", no_argument, NULL, OT_POSIX_OPT_DRY_RUN},
{"help", no_argument, NULL, OT_POSIX_OPT_HELP}, {"help", no_argument, NULL, OT_POSIX_OPT_HELP},
{"interface-name", required_argument, NULL, OT_POSIX_OPT_INTERFACE_NAME}, {"interface-name", required_argument, NULL, OT_POSIX_OPT_INTERFACE_NAME},
{"persistent-interface", no_argument, NULL, OT_POSIX_OPT_PERSISTENT_INTERFACE},
{"radio-version", no_argument, NULL, OT_POSIX_OPT_RADIO_VERSION}, {"radio-version", no_argument, NULL, OT_POSIX_OPT_RADIO_VERSION},
{"real-time-signal", required_argument, NULL, OT_POSIX_OPT_REAL_TIME_SIGNAL}, {"real-time-signal", required_argument, NULL, OT_POSIX_OPT_REAL_TIME_SIGNAL},
{"time-speed", required_argument, NULL, OT_POSIX_OPT_TIME_SPEED}, {"time-speed", required_argument, NULL, OT_POSIX_OPT_TIME_SPEED},
@@ -174,6 +176,7 @@ static void PrintUsage(const char *aProgramName, FILE *aStream, int aExitCode)
" -I --interface-name name Thread network interface name.\n" " -I --interface-name name Thread network interface name.\n"
" -n --dry-run Just verify if arguments is valid and radio spinel is compatible.\n" " -n --dry-run Just verify if arguments is valid and radio spinel is compatible.\n"
" --radio-version Print radio firmware version.\n" " --radio-version Print radio firmware version.\n"
" -p --persistent-interface Persistent the created thread network interface\n"
" -s --time-speed factor Time speed up factor.\n" " -s --time-speed factor Time speed up factor.\n"
" -v --verbose Also log to stderr.\n", " -v --verbose Also log to stderr.\n",
aProgramName); aProgramName);
@@ -191,8 +194,9 @@ static void ParseArg(int aArgCount, char *aArgVector[], PosixConfig *aConfig)
{ {
memset(aConfig, 0, sizeof(*aConfig)); memset(aConfig, 0, sizeof(*aConfig));
aConfig->mPlatformConfig.mSpeedUpFactor = 1; aConfig->mPlatformConfig.mPersistentInterface = false;
aConfig->mLogLevel = OT_LOG_LEVEL_CRIT; aConfig->mPlatformConfig.mSpeedUpFactor = 1;
aConfig->mLogLevel = OT_LOG_LEVEL_CRIT;
#ifdef __linux__ #ifdef __linux__
aConfig->mPlatformConfig.mRealTimeSignal = SIGRTMIN; aConfig->mPlatformConfig.mRealTimeSignal = SIGRTMIN;
#endif #endif
@@ -202,7 +206,7 @@ static void ParseArg(int aArgCount, char *aArgVector[], PosixConfig *aConfig)
while (true) while (true)
{ {
int index = 0; int index = 0;
int option = getopt_long(aArgCount, aArgVector, "B:d:hI:ns:v", kOptions, &index); int option = getopt_long(aArgCount, aArgVector, "B:d:hI:nps:v", kOptions, &index);
if (option == -1) if (option == -1)
{ {
@@ -220,6 +224,9 @@ static void ParseArg(int aArgCount, char *aArgVector[], PosixConfig *aConfig)
case OT_POSIX_OPT_INTERFACE_NAME: case OT_POSIX_OPT_INTERFACE_NAME:
aConfig->mPlatformConfig.mInterfaceName = optarg; aConfig->mPlatformConfig.mInterfaceName = optarg;
break; break;
case OT_POSIX_OPT_PERSISTENT_INTERFACE:
aConfig->mPlatformConfig.mPersistentInterface = true;
break;
case OT_POSIX_OPT_BACKBONE_INTERFACE_NAME: case OT_POSIX_OPT_BACKBONE_INTERFACE_NAME:
aConfig->mPlatformConfig.mBackboneInterfaceName = optarg; aConfig->mPlatformConfig.mBackboneInterfaceName = optarg;
break; break;
@@ -80,6 +80,7 @@ typedef struct otPlatformConfig
uint8_t mRadioUrlNum; ///< Number of Radio URLs. uint8_t mRadioUrlNum; ///< Number of Radio URLs.
int mRealTimeSignal; ///< The real-time signal for microsecond timer. int mRealTimeSignal; ///< The real-time signal for microsecond timer.
uint32_t mSpeedUpFactor; ///< Speed up factor. uint32_t mSpeedUpFactor; ///< Speed up factor.
bool mPersistentInterface; ///< Whether persistent the interface
bool mDryRun; ///< If 'DryRun' is set, the posix daemon will exit bool mDryRun; ///< If 'DryRun' is set, the posix daemon will exit
///< directly after initialization. ///< directly after initialization.
} otPlatformConfig; } otPlatformConfig;
+46 -25
View File
@@ -533,12 +533,13 @@ exit:
SuccessOrDie(error); SuccessOrDie(error);
} }
static void UpdateLink(otInstance *aInstance) static void SetLinkState(otInstance *aInstance, bool aState)
{ {
OT_UNUSED_VARIABLE(aInstance);
otError error = OT_ERROR_NONE; otError error = OT_ERROR_NONE;
struct ifreq ifr; struct ifreq ifr;
bool ifState = false; bool ifState = false;
bool otState = false;
assert(gInstance == aInstance); assert(gInstance == aInstance);
@@ -548,14 +549,13 @@ static void UpdateLink(otInstance *aInstance)
VerifyOrExit(ioctl(sIpFd, SIOCGIFFLAGS, &ifr) == 0, perror("ioctl"); error = OT_ERROR_FAILED); VerifyOrExit(ioctl(sIpFd, SIOCGIFFLAGS, &ifr) == 0, perror("ioctl"); error = OT_ERROR_FAILED);
ifState = ((ifr.ifr_flags & IFF_UP) == IFF_UP) ? true : false; ifState = ((ifr.ifr_flags & IFF_UP) == IFF_UP) ? true : false;
otState = otIp6IsEnabled(aInstance);
otLogNotePlat("[netif] Changing interface state to %s%s.", otState ? "up" : "down", otLogNotePlat("[netif] Changing interface state to %s%s.", aState ? "up" : "down",
(ifState == otState) ? " (already done, ignoring)" : ""); (ifState == aState) ? " (already done, ignoring)" : "");
if (ifState != otState) if (ifState != aState)
{ {
ifr.ifr_flags = otState ? (ifr.ifr_flags | IFF_UP) : (ifr.ifr_flags & ~IFF_UP); ifr.ifr_flags = aState ? (ifr.ifr_flags | IFF_UP) : (ifr.ifr_flags & ~IFF_UP);
VerifyOrExit(ioctl(sIpFd, SIOCSIFFLAGS, &ifr) == 0, perror("ioctl"); error = OT_ERROR_FAILED); VerifyOrExit(ioctl(sIpFd, SIOCSIFFLAGS, &ifr) == 0, perror("ioctl"); error = OT_ERROR_FAILED);
#if defined(RTM_NEWLINK) && defined(RTM_DELLINK) #if defined(RTM_NEWLINK) && defined(RTM_DELLINK)
// wait for RTM_NEWLINK event before processing notification from kernel to avoid infinite loop // wait for RTM_NEWLINK event before processing notification from kernel to avoid infinite loop
@@ -570,6 +570,12 @@ exit:
} }
} }
static void UpdateLink(otInstance *aInstance)
{
assert(gInstance == aInstance);
SetLinkState(aInstance, otIp6IsEnabled(aInstance));
}
#if defined(__linux__) #if defined(__linux__)
template <size_t N> otError AddRoute(const uint8_t (&aAddress)[N], uint8_t aPrefixLen, uint32_t aPriority) template <size_t N> otError AddRoute(const uint8_t (&aAddress)[N], uint8_t aPrefixLen, uint32_t aPriority)
{ {
@@ -1597,21 +1603,27 @@ exit:
#if defined(__linux__) #if defined(__linux__)
// set up the tun device // set up the tun device
static void platformConfigureTunDevice(const char *aInterfaceName, char *deviceName, size_t deviceNameLen) static void platformConfigureTunDevice(otPlatformConfig *aPlatformConfig)
{ {
struct ifreq ifr; struct ifreq ifr;
const char * interfaceName;
sTunFd = open(OPENTHREAD_POSIX_TUN_DEVICE, O_RDWR | O_CLOEXEC | O_NONBLOCK); sTunFd = open(OPENTHREAD_POSIX_TUN_DEVICE, O_RDWR | O_CLOEXEC | O_NONBLOCK);
VerifyOrDie(sTunFd >= 0, OT_EXIT_ERROR_ERRNO); VerifyOrDie(sTunFd >= 0, OT_EXIT_ERROR_ERRNO);
memset(&ifr, 0, sizeof(ifr)); memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TUN | IFF_NO_PI | static_cast<short>(IFF_TUN_EXCL); ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
if (!aPlatformConfig->mPersistentInterface)
if (aInterfaceName)
{ {
VerifyOrDie(strlen(aInterfaceName) < IFNAMSIZ, OT_EXIT_INVALID_ARGUMENTS); ifr.ifr_flags |= static_cast<short>(IFF_TUN_EXCL);
}
strncpy(ifr.ifr_name, aInterfaceName, IFNAMSIZ); interfaceName = aPlatformConfig->mInterfaceName;
if (interfaceName)
{
VerifyOrDie(strlen(interfaceName) < IFNAMSIZ, OT_EXIT_INVALID_ARGUMENTS);
strncpy(ifr.ifr_name, interfaceName, IFNAMSIZ);
} }
else else
{ {
@@ -1619,9 +1631,18 @@ static void platformConfigureTunDevice(const char *aInterfaceName, char *deviceN
} }
VerifyOrDie(ioctl(sTunFd, TUNSETIFF, static_cast<void *>(&ifr)) == 0, OT_EXIT_ERROR_ERRNO); VerifyOrDie(ioctl(sTunFd, TUNSETIFF, static_cast<void *>(&ifr)) == 0, OT_EXIT_ERROR_ERRNO);
VerifyOrDie(ioctl(sTunFd, TUNSETLINK, ARPHRD_VOID) == 0, OT_EXIT_ERROR_ERRNO);
strncpy(deviceName, ifr.ifr_name, deviceNameLen); strncpy(gNetifName, ifr.ifr_name, sizeof(gNetifName));
if (aPlatformConfig->mPersistentInterface)
{
VerifyOrDie(ioctl(sTunFd, TUNSETPERSIST, 1) == 0, OT_EXIT_ERROR_ERRNO);
// Set link down to reset the tun configuration.
// This will drop all existing IP addresses on the interface.
SetLinkState(gInstance, false);
}
VerifyOrDie(ioctl(sTunFd, TUNSETLINK, ARPHRD_VOID) == 0, OT_EXIT_ERROR_ERRNO);
ifr.ifr_mtu = static_cast<int>(kMaxIp6Size); ifr.ifr_mtu = static_cast<int>(kMaxIp6Size);
VerifyOrDie(ioctl(sIpFd, SIOCSIFMTU, static_cast<void *>(&ifr)) == 0, OT_EXIT_ERROR_ERRNO); VerifyOrDie(ioctl(sIpFd, SIOCSIFMTU, static_cast<void *>(&ifr)) == 0, OT_EXIT_ERROR_ERRNO);
@@ -1629,9 +1650,9 @@ static void platformConfigureTunDevice(const char *aInterfaceName, char *deviceN
#endif #endif
#if defined(__APPLE__) && (OPENTHREAD_POSIX_CONFIG_MACOS_TUN_OPTION == OT_POSIX_CONFIG_MACOS_UTUN) #if defined(__APPLE__) && (OPENTHREAD_POSIX_CONFIG_MACOS_TUN_OPTION == OT_POSIX_CONFIG_MACOS_UTUN)
static void platformConfigureTunDevice(const char *aInterfaceName, char *deviceName, size_t deviceNameLen) static void platformConfigureTunDevice(otPlatformConfig *aPlatformConfig)
{ {
(void)aInterfaceName; (void)aPlatformConfig;
int err = 0; int err = 0;
struct sockaddr_ctl addr; struct sockaddr_ctl addr;
struct ctl_info info; struct ctl_info info;
@@ -1654,11 +1675,11 @@ static void platformConfigureTunDevice(const char *aInterfaceName, char *deviceN
VerifyOrDie(err == 0, OT_EXIT_ERROR_ERRNO); VerifyOrDie(err == 0, OT_EXIT_ERROR_ERRNO);
socklen_t devNameLen; socklen_t devNameLen;
devNameLen = (socklen_t)deviceNameLen; devNameLen = (socklen_t)sizeof(gNetifName);
err = getsockopt(sTunFd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, deviceName, &devNameLen); err = getsockopt(sTunFd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, gNetifName, &devNameLen);
VerifyOrDie(err == 0, OT_EXIT_ERROR_ERRNO); VerifyOrDie(err == 0, OT_EXIT_ERROR_ERRNO);
otLogInfoPlat("[netif] Tunnel device name = '%s'", deviceName); otLogInfoPlat("[netif] Tunnel device name = '%s'", gNetifName);
} }
#endif #endif
@@ -1681,14 +1702,14 @@ exit:
#if defined(__NetBSD__) || \ #if defined(__NetBSD__) || \
(defined(__APPLE__) && (OPENTHREAD_POSIX_CONFIG_MACOS_TUN_OPTION == OT_POSIX_CONFIG_MACOS_TUN)) || \ (defined(__APPLE__) && (OPENTHREAD_POSIX_CONFIG_MACOS_TUN_OPTION == OT_POSIX_CONFIG_MACOS_TUN)) || \
defined(__FreeBSD__) defined(__FreeBSD__)
static void platformConfigureTunDevice(const char *aInterfaceName, char *deviceName, size_t deviceNameLen) static void platformConfigureTunDevice(otPlatformConfig *aPlatformConfig)
{ {
int flags = IFF_BROADCAST | IFF_MULTICAST; int flags = IFF_BROADCAST | IFF_MULTICAST;
int err; int err;
const char *last_slash; const char *last_slash;
const char *path; const char *path;
(void)aInterfaceName; (void)aPlatformConfig;
path = OPENTHREAD_POSIX_TUN_DEVICE; path = OPENTHREAD_POSIX_TUN_DEVICE;
@@ -1708,7 +1729,7 @@ static void platformConfigureTunDevice(const char *aInterfaceName, char *deviceN
VerifyOrDie(last_slash != nullptr, OT_EXIT_ERROR_ERRNO); VerifyOrDie(last_slash != nullptr, OT_EXIT_ERROR_ERRNO);
last_slash++; last_slash++;
strncpy(deviceName, last_slash, deviceNameLen); strncpy(gNetifName, last_slash, sizeof(gNetifName));
} }
#endif #endif
@@ -1760,13 +1781,13 @@ static void platformConfigureNetLink(void)
#endif // defined(__APPLE__) || defined(__NetBSD__) || defined(__FreeBSD__) #endif // defined(__APPLE__) || defined(__NetBSD__) || defined(__FreeBSD__)
} }
void platformNetifInit(const char *aInterfaceName) void platformNetifInit(otPlatformConfig *aPlatformConfig)
{ {
sIpFd = SocketWithCloseExec(AF_INET6, SOCK_DGRAM, IPPROTO_IP, kSocketNonBlock); sIpFd = SocketWithCloseExec(AF_INET6, SOCK_DGRAM, IPPROTO_IP, kSocketNonBlock);
VerifyOrDie(sIpFd >= 0, OT_EXIT_ERROR_ERRNO); VerifyOrDie(sIpFd >= 0, OT_EXIT_ERROR_ERRNO);
platformConfigureNetLink(); platformConfigureNetLink();
platformConfigureTunDevice(aInterfaceName, gNetifName, sizeof(gNetifName)); platformConfigureTunDevice(aPlatformConfig);
gNetifIndex = if_nametoindex(gNetifName); gNetifIndex = if_nametoindex(gNetifName);
VerifyOrDie(gNetifIndex > 0, OT_EXIT_FAILURE); VerifyOrDie(gNetifIndex > 0, OT_EXIT_FAILURE);
+1 -1
View File
@@ -244,7 +244,7 @@ void platformUartProcess(const fd_set *aReadFdSet, const fd_set *aWriteFdSet, co
* @param[in] aInterfaceName A pointer to Thread network interface name. * @param[in] aInterfaceName A pointer to Thread network interface name.
* *
*/ */
void platformNetifInit(const char *aInterfaceName); void platformNetifInit(otPlatformConfig *aPlatformConfig);
/** /**
* This function sets up platform netif. * This function sets up platform netif.
+1 -1
View File
@@ -154,7 +154,7 @@ void platformInit(otPlatformConfig *aPlatformConfig)
#endif #endif
#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE #if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE
platformNetifInit(aPlatformConfig->mInterfaceName); platformNetifInit(aPlatformConfig);
#endif #endif
#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE #if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE