[posix-netif] configure metric for prefix routes (#7605)
This commit allows configuring route metric for the prefix routes of
IPv6 addresses added to the Thread network interface.
This commit also simplifies `UpdateUnicastLinux` by using `AddRtAttr`.
diff --git a/src/posix/platform/netif.cpp b/src/posix/platform/netif.cpp
index 8b8adc6..04a80a9 100644
--- a/src/posix/platform/netif.cpp
+++ b/src/posix/platform/netif.cpp
@@ -322,10 +322,35 @@
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-align"
-static void UpdateUnicastLinux(const otIp6AddressInfo &aAddressInfo, bool aIsAdded)
+#if !defined(IFA_RT_PRIORITY)
+#define IFA_RT_PRIORITY 9
+#endif
+
+void AddRtAttr(struct nlmsghdr *aHeader, uint32_t aMaxLen, uint8_t aType, const void *aData, uint8_t aLen)
{
+ uint8_t len = RTA_LENGTH(aLen);
struct rtattr *rta;
+ assert(NLMSG_ALIGN(aHeader->nlmsg_len) + RTA_ALIGN(len) <= aMaxLen);
+ OT_UNUSED_VARIABLE(aMaxLen);
+
+ rta = (struct rtattr *)((char *)(aHeader) + NLMSG_ALIGN((aHeader)->nlmsg_len));
+ rta->rta_type = aType;
+ rta->rta_len = len;
+ if (aLen)
+ {
+ memcpy(RTA_DATA(rta), aData, aLen);
+ }
+ aHeader->nlmsg_len = NLMSG_ALIGN(aHeader->nlmsg_len) + RTA_ALIGN(len);
+}
+
+void AddRtAttrUint32(struct nlmsghdr *aHeader, uint32_t aMaxLen, uint8_t aType, uint32_t aData)
+{
+ AddRtAttr(aHeader, aMaxLen, aType, &aData, sizeof(aData));
+}
+
+static void UpdateUnicastLinux(const otIp6AddressInfo &aAddressInfo, bool aIsAdded)
+{
struct
{
struct nlmsghdr nh;
@@ -347,30 +372,25 @@
req.ifa.ifa_scope = aAddressInfo.mScope;
req.ifa.ifa_index = gNetifIndex;
- rta = reinterpret_cast<struct rtattr *>((reinterpret_cast<char *>(&req)) + NLMSG_ALIGN(req.nh.nlmsg_len));
- rta->rta_type = IFA_LOCAL;
- rta->rta_len = RTA_LENGTH(sizeof(*aAddressInfo.mAddress));
-
- memcpy(RTA_DATA(rta), aAddressInfo.mAddress, sizeof(*aAddressInfo.mAddress));
-
- req.nh.nlmsg_len = NLMSG_ALIGN(req.nh.nlmsg_len) + rta->rta_len;
+ AddRtAttr(&req.nh, sizeof(req), IFA_LOCAL, aAddressInfo.mAddress, sizeof(*aAddressInfo.mAddress));
if (!aAddressInfo.mPreferred)
{
struct ifa_cacheinfo cacheinfo;
- rta = reinterpret_cast<struct rtattr *>((reinterpret_cast<char *>(rta)) + rta->rta_len);
- rta->rta_type = IFA_CACHEINFO;
- rta->rta_len = RTA_LENGTH(sizeof(cacheinfo));
-
memset(&cacheinfo, 0, sizeof(cacheinfo));
cacheinfo.ifa_valid = UINT32_MAX;
- memcpy(RTA_DATA(rta), &cacheinfo, sizeof(cacheinfo));
-
- req.nh.nlmsg_len += rta->rta_len;
+ AddRtAttr(&req.nh, sizeof(req), IFA_CACHEINFO, &cacheinfo, sizeof(cacheinfo));
}
+#if OPENTHREAD_POSIX_CONFIG_NETIF_PREFIX_ROUTE_METRIC > 0
+ if (aAddressInfo.mScope > ot::Ip6::Address::kLinkLocalScope)
+ {
+ AddRtAttrUint32(&req.nh, sizeof(req), IFA_RT_PRIORITY, OPENTHREAD_POSIX_CONFIG_NETIF_PREFIX_ROUTE_METRIC);
+ }
+#endif
+
if (send(sNetlinkFd, &req, req.nh.nlmsg_len, 0) != -1)
{
otLogInfoPlat("[netif] Sent request#%u to %s %s/%u", sNetlinkSequence, (aIsAdded ? "add" : "remove"),
@@ -516,29 +536,6 @@
}
#if OPENTHREAD_POSIX_CONFIG_INSTALL_EXTERNAL_ROUTES_ENABLE && __linux__
-void AddRtAttr(struct nlmsghdr *aHeader, uint32_t aMaxLen, uint8_t aType, const void *aData, uint8_t aLen)
-{
- uint8_t len = RTA_LENGTH(aLen);
- struct rtattr *rta;
-
- assert(NLMSG_ALIGN(aHeader->nlmsg_len) + RTA_ALIGN(len) <= aMaxLen);
- OT_UNUSED_VARIABLE(aMaxLen);
-
- rta = (struct rtattr *)((char *)(aHeader) + NLMSG_ALIGN((aHeader)->nlmsg_len));
- rta->rta_type = aType;
- rta->rta_len = len;
- if (aLen)
- {
- memcpy(RTA_DATA(rta), aData, aLen);
- }
- aHeader->nlmsg_len = NLMSG_ALIGN(aHeader->nlmsg_len) + RTA_ALIGN(len);
-}
-
-void AddRtAttrUint32(struct nlmsghdr *aHeader, uint32_t aMaxLen, uint8_t aType, uint32_t aData)
-{
- AddRtAttr(aHeader, aMaxLen, aType, &aData, sizeof(aData));
-}
-
static otError AddExternalRoute(const otIp6Prefix &aPrefix)
{
constexpr unsigned int kBufSize = 128;
diff --git a/src/posix/platform/openthread-posix-config.h b/src/posix/platform/openthread-posix-config.h
index 9abf0ad..a348a17 100644
--- a/src/posix/platform/openthread-posix-config.h
+++ b/src/posix/platform/openthread-posix-config.h
@@ -127,6 +127,17 @@
#endif
/**
+ * @def OPENTHREAD_POSIX_CONFIG_NETIF_PREFIX_ROUTE_METRIC
+ *
+ * This setting configures the prefix route metric on the Thread network interface.
+ * Define as 0 to use use the default prefix route metric.
+ *
+ */
+#ifndef OPENTHREAD_POSIX_CONFIG_NETIF_PREFIX_ROUTE_METRIC
+#define OPENTHREAD_POSIX_CONFIG_NETIF_PREFIX_ROUTE_METRIC 0
+#endif
+
+/**
* @def OPENTHREAD_POSIX_CONFIG_INSTALL_EXTERNAL_ROUTES_ENABLE
*
* Define as 1 to add external routes to POSIX kernel when external routes are changed in netdata.