[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_HELP = 'h',
OT_POSIX_OPT_INTERFACE_NAME = 'I',
OT_POSIX_OPT_PERSISTENT_INTERFACE = 'p',
OT_POSIX_OPT_TIME_SPEED = 's',
OT_POSIX_OPT_VERBOSE = 'v',
@@ -156,6 +157,7 @@ static const struct option kOptions[] = {
{"dry-run", no_argument, NULL, OT_POSIX_OPT_DRY_RUN},
{"help", no_argument, NULL, OT_POSIX_OPT_HELP},
{"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},
{"real-time-signal", required_argument, NULL, OT_POSIX_OPT_REAL_TIME_SIGNAL},
{"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"
" -n --dry-run Just verify if arguments is valid and radio spinel is compatible.\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"
" -v --verbose Also log to stderr.\n",
aProgramName);
@@ -191,8 +194,9 @@ static void ParseArg(int aArgCount, char *aArgVector[], PosixConfig *aConfig)
{
memset(aConfig, 0, sizeof(*aConfig));
aConfig->mPlatformConfig.mSpeedUpFactor = 1;
aConfig->mLogLevel = OT_LOG_LEVEL_CRIT;
aConfig->mPlatformConfig.mPersistentInterface = false;
aConfig->mPlatformConfig.mSpeedUpFactor = 1;
aConfig->mLogLevel = OT_LOG_LEVEL_CRIT;
#ifdef __linux__
aConfig->mPlatformConfig.mRealTimeSignal = SIGRTMIN;
#endif
@@ -202,7 +206,7 @@ static void ParseArg(int aArgCount, char *aArgVector[], PosixConfig *aConfig)
while (true)
{
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)
{
@@ -220,6 +224,9 @@ static void ParseArg(int aArgCount, char *aArgVector[], PosixConfig *aConfig)
case OT_POSIX_OPT_INTERFACE_NAME:
aConfig->mPlatformConfig.mInterfaceName = optarg;
break;
case OT_POSIX_OPT_PERSISTENT_INTERFACE:
aConfig->mPlatformConfig.mPersistentInterface = true;
break;
case OT_POSIX_OPT_BACKBONE_INTERFACE_NAME:
aConfig->mPlatformConfig.mBackboneInterfaceName = optarg;
break;
@@ -80,6 +80,7 @@ typedef struct otPlatformConfig
uint8_t mRadioUrlNum; ///< Number of Radio URLs.
int mRealTimeSignal; ///< The real-time signal for microsecond timer.
uint32_t mSpeedUpFactor; ///< Speed up factor.
bool mPersistentInterface; ///< Whether persistent the interface
bool mDryRun; ///< If 'DryRun' is set, the posix daemon will exit
///< directly after initialization.
} otPlatformConfig;
+46 -25
View File
@@ -533,12 +533,13 @@ exit:
SuccessOrDie(error);
}
static void UpdateLink(otInstance *aInstance)
static void SetLinkState(otInstance *aInstance, bool aState)
{
OT_UNUSED_VARIABLE(aInstance);
otError error = OT_ERROR_NONE;
struct ifreq ifr;
bool ifState = false;
bool otState = false;
assert(gInstance == aInstance);
@@ -548,14 +549,13 @@ static void UpdateLink(otInstance *aInstance)
VerifyOrExit(ioctl(sIpFd, SIOCGIFFLAGS, &ifr) == 0, perror("ioctl"); error = OT_ERROR_FAILED);
ifState = ((ifr.ifr_flags & IFF_UP) == IFF_UP) ? true : false;
otState = otIp6IsEnabled(aInstance);
otLogNotePlat("[netif] Changing interface state to %s%s.", otState ? "up" : "down",
(ifState == otState) ? " (already done, ignoring)" : "");
otLogNotePlat("[netif] Changing interface state to %s%s.", aState ? "up" : "down",
(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);
#if defined(RTM_NEWLINK) && defined(RTM_DELLINK)
// 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__)
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__)
// set up the tun device
static void platformConfigureTunDevice(const char *aInterfaceName, char *deviceName, size_t deviceNameLen)
static void platformConfigureTunDevice(otPlatformConfig *aPlatformConfig)
{
struct ifreq ifr;
const char * interfaceName;
sTunFd = open(OPENTHREAD_POSIX_TUN_DEVICE, O_RDWR | O_CLOEXEC | O_NONBLOCK);
VerifyOrDie(sTunFd >= 0, OT_EXIT_ERROR_ERRNO);
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TUN | IFF_NO_PI | static_cast<short>(IFF_TUN_EXCL);
if (aInterfaceName)
ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
if (!aPlatformConfig->mPersistentInterface)
{
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
{
@@ -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, 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);
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
#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;
struct sockaddr_ctl addr;
struct ctl_info info;
@@ -1654,11 +1675,11 @@ static void platformConfigureTunDevice(const char *aInterfaceName, char *deviceN
VerifyOrDie(err == 0, OT_EXIT_ERROR_ERRNO);
socklen_t devNameLen;
devNameLen = (socklen_t)deviceNameLen;
err = getsockopt(sTunFd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, deviceName, &devNameLen);
devNameLen = (socklen_t)sizeof(gNetifName);
err = getsockopt(sTunFd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, gNetifName, &devNameLen);
VerifyOrDie(err == 0, OT_EXIT_ERROR_ERRNO);
otLogInfoPlat("[netif] Tunnel device name = '%s'", deviceName);
otLogInfoPlat("[netif] Tunnel device name = '%s'", gNetifName);
}
#endif
@@ -1681,14 +1702,14 @@ exit:
#if defined(__NetBSD__) || \
(defined(__APPLE__) && (OPENTHREAD_POSIX_CONFIG_MACOS_TUN_OPTION == OT_POSIX_CONFIG_MACOS_TUN)) || \
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 err;
const char *last_slash;
const char *path;
(void)aInterfaceName;
(void)aPlatformConfig;
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);
last_slash++;
strncpy(deviceName, last_slash, deviceNameLen);
strncpy(gNetifName, last_slash, sizeof(gNetifName));
}
#endif
@@ -1760,13 +1781,13 @@ static void platformConfigureNetLink(void)
#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);
VerifyOrDie(sIpFd >= 0, OT_EXIT_ERROR_ERRNO);
platformConfigureNetLink();
platformConfigureTunDevice(aInterfaceName, gNetifName, sizeof(gNetifName));
platformConfigureTunDevice(aPlatformConfig);
gNetifIndex = if_nametoindex(gNetifName);
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.
*
*/
void platformNetifInit(const char *aInterfaceName);
void platformNetifInit(otPlatformConfig *aPlatformConfig);
/**
* This function sets up platform netif.
+1 -1
View File
@@ -154,7 +154,7 @@ void platformInit(otPlatformConfig *aPlatformConfig)
#endif
#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE
platformNetifInit(aPlatformConfig->mInterfaceName);
platformNetifInit(aPlatformConfig);
#endif
#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE