Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inet: Move some InterfaceId functions out of InetLayer #11673

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 118 additions & 0 deletions src/inet/InetInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,35 @@ bool InterfaceAddressIterator::HasBroadcastAddress()
return HasCurrent() && mIntfIter.HasBroadcastAddress();
}

CHIP_ERROR InterfaceId::GetLinkLocalAddr(IPAddress * llAddr)
{
VerifyOrReturnError(llAddr != nullptr, CHIP_ERROR_INVALID_ARGUMENT);

#if !LWIP_IPV6
return CHIP_ERROR_NOT_IMPLEMENTED;
#endif //! LWIP_IPV6

for (struct netif * intf = netif_list; intf != nullptr; intf = intf->next)
{
if ((mPlatformInterface != nullptr) && (mPlatformInterface != intf))
continue;
for (int j = 0; j < LWIP_IPV6_NUM_ADDRESSES; ++j)
{
if (ip6_addr_isvalid(netif_ip6_addr_state(intf, j)) && ip6_addr_islinklocal(netif_ip6_addr(intf, j)))
{
(*llAddr) = IPAddress(*netif_ip6_addr(intf, j));
return CHIP_NO_ERROR;
}
}
if (mPlatformInterface != nullptr)
{
return INET_ERROR_ADDRESS_NOT_FOUND;
}
}

return CHIP_NO_ERROR;
}

#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
Expand Down Expand Up @@ -704,6 +733,38 @@ bool InterfaceAddressIterator::HasBroadcastAddress()
return HasCurrent() && (mCurAddr->ifa_flags & IFF_BROADCAST) != 0;
}

CHIP_ERROR InterfaceId::GetLinkLocalAddr(IPAddress * llAddr)
{
VerifyOrReturnError(llAddr != nullptr, CHIP_ERROR_INVALID_ARGUMENT);

struct ifaddrs * ifaddr;
const int rv = getifaddrs(&ifaddr);
if (rv == -1)
{
return INET_ERROR_ADDRESS_NOT_FOUND;
}

for (struct ifaddrs * ifaddr_iter = ifaddr; ifaddr_iter != nullptr; ifaddr_iter = ifaddr_iter->ifa_next)
{
if (ifaddr_iter->ifa_addr != nullptr)
{
if ((ifaddr_iter->ifa_addr->sa_family == AF_INET6) &&
((mPlatformInterface == 0) || (mPlatformInterface == if_nametoindex(ifaddr_iter->ifa_name))))
{
struct in6_addr * sin6_addr = &(reinterpret_cast<struct sockaddr_in6 *>(ifaddr_iter->ifa_addr))->sin6_addr;
if (sin6_addr->s6_addr[0] == 0xfe && (sin6_addr->s6_addr[1] & 0xc0) == 0x80) // Link Local Address
{
(*llAddr) = IPAddress((reinterpret_cast<struct sockaddr_in6 *>(ifaddr_iter->ifa_addr))->sin6_addr);
break;
}
}
}
}
freeifaddrs(ifaddr);

return CHIP_NO_ERROR;
}

#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
Expand Down Expand Up @@ -865,8 +926,65 @@ bool InterfaceAddressIterator::HasBroadcastAddress()
return HasCurrent() && mIntfIter.HasBroadcastAddress();
}

CHIP_ERROR InterfaceId::GetLinkLocalAddr(IPAddress * llAddr)
{
VerifyOrReturnError(llAddr != nullptr, CHIP_ERROR_INVALID_ARGUMENT);

net_if * const iface = mPlatformInterface ? net_if_get_by_index(mPlatformInterface) : net_if_get_default();
VerifyOrReturnError(iface != nullptr, INET_ERROR_ADDRESS_NOT_FOUND);

in6_addr * const ip6_addr = net_if_ipv6_get_ll(iface, NET_ADDR_PREFERRED);
VerifyOrReturnError(ip6_addr != nullptr, INET_ERROR_ADDRESS_NOT_FOUND);

*llAddr = IPAddress(*ip6_addr);

return CHIP_NO_ERROR;
}

#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF

// static
InterfaceId InterfaceId::FromIPAddress(const IPAddress & addr)
{
InterfaceAddressIterator addrIter;

for (; addrIter.HasCurrent(); addrIter.Next())
{
IPAddress curAddr = addrIter.GetAddress();
if (addr == curAddr)
{
return addrIter.GetInterfaceId();
}
}

return InterfaceId::Null();
}

// static
bool InterfaceId::MatchLocalIPv6Subnet(const IPAddress & addr)
{
if (addr.IsIPv6LinkLocal())
return true;

InterfaceAddressIterator ifAddrIter;
for (; ifAddrIter.HasCurrent(); ifAddrIter.Next())
{
IPPrefix addrPrefix;
addrPrefix.IPAddr = ifAddrIter.GetAddress();
#if INET_CONFIG_ENABLE_IPV4
if (addrPrefix.IPAddr.IsIPv4())
continue;
#endif // INET_CONFIG_ENABLE_IPV4
if (addrPrefix.IPAddr.IsIPv6LinkLocal())
continue;
addrPrefix.Length = ifAddrIter.GetPrefixLength();
if (addrPrefix.MatchAddress(addr))
return true;
}

return false;
}

void InterfaceAddressIterator::GetAddressWithPrefix(IPPrefix & addrWithPrefix)
{
if (HasCurrent())
Expand Down
33 changes: 33 additions & 0 deletions src/inet/InetInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,39 @@ class InterfaceId
*/
static CHIP_ERROR InterfaceNameToId(const char * intfName, InterfaceId & intfId);

/**
* Get the interface identifier for the specified IP address. If the
* interface identifier cannot be derived it is set to the default InterfaceId.
*
* @note
* This function fetches the first interface (from the configured list
* of interfaces) that matches the specified IP address.
*/
static InterfaceId FromIPAddress(const IPAddress & addr);

/**
* Check if there is a prefix match between the specified IPv6 address and any of
* the locally configured IPv6 addresses.
*
* @param[in] addr The IPv6 address to check for the prefix-match.
* @return true if a successful match is found, otherwise false.
*/
static bool MatchLocalIPv6Subnet(const IPAddress & addr);

/**
* Get the link local IPv6 address.
*
* @param[out] llAddr The link local IPv6 address for the link.
*
* @retval #CHIP_ERROR_NOT_IMPLEMENTED If IPv6 is not supported.
* @retval #CHIP_ERROR_INVALID_ARGUMENT If the link local address
* is nullptr.
* @retval #INET_ERROR_ADDRESS_NOT_FOUND If the link does not have
* any address configured.
* @retval #CHIP_NO_ERROR On success.
*/
CHIP_ERROR GetLinkLocalAddr(IPAddress * llAddr);

private:
#if CHIP_SYSTEM_CONFIG_USE_LWIP
static constexpr PlatformType kPlatformNull = nullptr;
Expand Down
153 changes: 0 additions & 153 deletions src/inet/InetLayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,91 +318,6 @@ bool InetLayer::IsIdleTimerRunning()
}
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT && INET_TCP_IDLE_CHECK_INTERVAL > 0

/**
* Get the link local IPv6 address for a specified link or interface.
*
* @param[in] interface The interface for which the link local IPv6
* address is being sought.
*
* @param[out] llAddr The link local IPv6 address for the link.
*
* @retval #CHIP_ERROR_NOT_IMPLEMENTED If IPv6 is not supported.
* @retval #CHIP_ERROR_INVALID_ARGUMENT If the link local address
* is nullptr.
* @retval #INET_ERROR_ADDRESS_NOT_FOUND If the link does not have
* any address configured.
* @retval #CHIP_NO_ERROR On success.
*
*/
CHIP_ERROR InetLayer::GetLinkLocalAddr(InterfaceId interface, IPAddress * llAddr)
{
VerifyOrReturnError(llAddr != nullptr, CHIP_ERROR_INVALID_ARGUMENT);

#if CHIP_SYSTEM_CONFIG_USE_LWIP
#if !LWIP_IPV6
return CHIP_ERROR_NOT_IMPLEMENTED;
#endif //! LWIP_IPV6

struct netif * link = interface.GetPlatformInterface();
for (struct netif * intf = netif_list; intf != NULL; intf = intf->next)
{
if ((link != NULL) && (link != intf))
continue;
for (int j = 0; j < LWIP_IPV6_NUM_ADDRESSES; ++j)
{
if (ip6_addr_isvalid(netif_ip6_addr_state(intf, j)) && ip6_addr_islinklocal(netif_ip6_addr(intf, j)))
{
(*llAddr) = IPAddress(*netif_ip6_addr(intf, j));
return CHIP_NO_ERROR;
}
}
if (link != NULL)
{
return INET_ERROR_ADDRESS_NOT_FOUND;
}
}
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
struct ifaddrs * ifaddr;
const int rv = getifaddrs(&ifaddr);
if (rv == -1)
{
return INET_ERROR_ADDRESS_NOT_FOUND;
}

for (struct ifaddrs * ifaddr_iter = ifaddr; ifaddr_iter != nullptr; ifaddr_iter = ifaddr_iter->ifa_next)
{
if (ifaddr_iter->ifa_addr != nullptr)
{
if ((ifaddr_iter->ifa_addr->sa_family == AF_INET6) &&
(!interface.IsPresent() || (if_nametoindex(ifaddr_iter->ifa_name) == interface.GetPlatformInterface())))
{
struct in6_addr * sin6_addr = &(reinterpret_cast<struct sockaddr_in6 *>(ifaddr_iter->ifa_addr))->sin6_addr;
if (sin6_addr->s6_addr[0] == 0xfe && (sin6_addr->s6_addr[1] & 0xc0) == 0x80) // Link Local Address
{
(*llAddr) = IPAddress((reinterpret_cast<struct sockaddr_in6 *>(ifaddr_iter->ifa_addr))->sin6_addr);
break;
}
}
}
}
freeifaddrs(ifaddr);
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
net_if * const iface = interface.IsPresent() ? net_if_get_by_index(interface.GetPlatformInterface()) : net_if_get_default();
VerifyOrReturnError(iface != nullptr, INET_ERROR_ADDRESS_NOT_FOUND);

in6_addr * const ip6_addr = net_if_ipv6_get_ll(iface, NET_ADDR_PREFERRED);
VerifyOrReturnError(ip6_addr != nullptr, INET_ERROR_ADDRESS_NOT_FOUND);

*llAddr = IPAddress(*ip6_addr);
#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF

return CHIP_NO_ERROR;
}

#if INET_CONFIG_ENABLE_TCP_ENDPOINT
/**
* Creates a new TCPEndPoint object.
Expand Down Expand Up @@ -481,74 +396,6 @@ CHIP_ERROR InetLayer::NewUDPEndPoint(UDPEndPoint ** retEndPoint)
}
#endif // INET_CONFIG_ENABLE_UDP_ENDPOINT

/**
* Get the interface identifier for the specified IP address. If the
* interface identifier cannot be derived it is set to the default
* InterfaceId.
*
* @note
* This function fetches the first interface (from the configured list
* of interfaces) that matches the specified IP address.
*
* @param[in] addr A reference to the IPAddress object.
*
* @param[out] intfId A reference to the InterfaceId object.
*
* @return #CHIP_NO_ERROR unconditionally.
*
*/
CHIP_ERROR InetLayer::GetInterfaceFromAddr(const IPAddress & addr, InterfaceId & intfId)
{
InterfaceAddressIterator addrIter;

for (; addrIter.HasCurrent(); addrIter.Next())
{
IPAddress curAddr = addrIter.GetAddress();
if (addr == curAddr)
{
intfId = addrIter.GetInterfaceId();
return CHIP_NO_ERROR;
}
}

intfId = InterfaceId::Null();

return CHIP_NO_ERROR;
}

/**
* Check if there is a prefix match between the specified IPv6 address and any of
* the locally configured IPv6 addresses.
*
* @param[in] addr The IPv6 address to check for the prefix-match.
*
* @return true if a successful match is found, otherwise false.
*
*/
bool InetLayer::MatchLocalIPv6Subnet(const IPAddress & addr)
{
if (addr.IsIPv6LinkLocal())
return true;

InterfaceAddressIterator ifAddrIter;
for (; ifAddrIter.HasCurrent(); ifAddrIter.Next())
{
IPPrefix addrPrefix;
addrPrefix.IPAddr = ifAddrIter.GetAddress();
#if INET_CONFIG_ENABLE_IPV4
if (addrPrefix.IPAddr.IsIPv4())
continue;
#endif // INET_CONFIG_ENABLE_IPV4
if (addrPrefix.IPAddr.IsIPv6LinkLocal())
continue;
addrPrefix.Length = ifAddrIter.GetPrefixLength();
if (addrPrefix.MatchAddress(addr))
return true;
}

return false;
}

#if INET_CONFIG_ENABLE_TCP_ENDPOINT && INET_TCP_IDLE_CHECK_INTERVAL > 0
void InetLayer::HandleTCPInactivityTimer(chip::System::Layer * aSystemLayer, void * aAppState)
{
Expand Down
7 changes: 0 additions & 7 deletions src/inet/InetLayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,13 +143,6 @@ class DLL_EXPORT InetLayer
CHIP_ERROR NewUDPEndPoint(UDPEndPoint ** retEndPoint);
#endif // INET_CONFIG_ENABLE_UDP_ENDPOINT

// DNS Resolution

CHIP_ERROR GetInterfaceFromAddr(const IPAddress & addr, InterfaceId & intfId);

CHIP_ERROR GetLinkLocalAddr(InterfaceId link, IPAddress * llAddr);
bool MatchLocalIPv6Subnet(const IPAddress & addr);

void * GetPlatformData();
void SetPlatformData(void * aPlatformData);

Expand Down
3 changes: 1 addition & 2 deletions src/inet/TCPEndPoint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,12 +195,11 @@ CHIP_ERROR TCPEndPoint::ConnectImpl(const IPAddress & addr, uint16_t port, Inter
if (intfId.IsPresent())
{
IPAddress intfLLAddr;
InetLayer & lInetLayer = Layer();

if (!addr.IsIPv6LinkLocal() || mState == State::kBound)
return CHIP_ERROR_NOT_IMPLEMENTED;

res = lInetLayer.GetLinkLocalAddr(intfId, &intfLLAddr);
res = intfId.GetLinkLocalAddr(&intfLLAddr);
if (res != CHIP_NO_ERROR)
return res;

Expand Down
Loading