util: Refactor isValidPrefix to reduce address family re-use
Change-Id: I13abd5b110709210b98b4ea74e3129c3ab42bd46
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/util.cpp b/src/util.cpp
index 7935ba6..cef2966 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -138,6 +138,19 @@
} // namespace internal
+constexpr auto familyVisit(auto&& visitor, int family)
+{
+ if (family == AF_INET)
+ {
+ return visitor.template operator()<AF_INET>();
+ }
+ else if (family == AF_INET6)
+ {
+ return visitor.template operator()<AF_INET6>();
+ }
+ throw std::invalid_argument("Invalid addr family");
+}
+
std::string toMask(int addressFamily, uint8_t prefix)
{
if (addressFamily == AF_INET6)
@@ -234,27 +247,10 @@
return inet_pton(addressFamily, address.c_str(), buf) > 0;
}
-bool isValidPrefix(int addressFamily, uint8_t prefixLength)
+bool isValidPrefix(int family, uint8_t prefix)
{
- if (addressFamily == AF_INET)
- {
- if (prefixLength < IPV4_MIN_PREFIX_LENGTH ||
- prefixLength > IPV4_MAX_PREFIX_LENGTH)
- {
- return false;
- }
- }
-
- if (addressFamily == AF_INET6)
- {
- if (prefixLength < IPV4_MIN_PREFIX_LENGTH ||
- prefixLength > IPV6_MAX_PREFIX_LENGTH)
- {
- return false;
- }
- }
-
- return true;
+ return familyVisit(
+ [=]<int f>() noexcept { return isValidPrefix<f>(prefix); }, family);
}
InterfaceList getInterfaces()
diff --git a/src/util.hpp b/src/util.hpp
index dece269..f98a7d5 100644
--- a/src/util.hpp
+++ b/src/util.hpp
@@ -2,6 +2,7 @@
#include "types.hpp"
#include <netinet/ether.h>
+#include <netinet/in.h>
#include <unistd.h>
#include <cstring>
@@ -26,10 +27,6 @@
using EthernetInterfaceIntf =
sdbusplus::xyz::openbmc_project::Network::server::EthernetInterface;
-constexpr auto IPV4_MIN_PREFIX_LENGTH = 1;
-constexpr auto IPV4_MAX_PREFIX_LENGTH = 32;
-constexpr auto IPV6_MAX_PREFIX_LENGTH = 128;
-
namespace mac_address
{
@@ -75,6 +72,23 @@
constexpr auto networkdService = "systemd-networkd.service";
constexpr auto timeSynchdService = "systemd-timesyncd.service";
+template <int family>
+struct FamilyTraits
+{
+};
+
+template <>
+struct FamilyTraits<AF_INET>
+{
+ using addr = in_addr;
+};
+
+template <>
+struct FamilyTraits<AF_INET6>
+{
+ using addr = in6_addr;
+};
+
/* @brief converts a sockaddr for the specified address family into
* a type_safe InAddrAny.
* @param[in] addressFamily - The address family of the buf
@@ -98,11 +112,16 @@
bool isValidIP(int addressFamily, stdplus::const_zstring address);
/* @brief checks that the given prefix is valid or not.
- * @param[in] addressFamily - IP address family(AF_INET/AF_INET6).
+ * @param[in] family - IP address family(AF_INET/AF_INET6).
* @param[in] prefix - prefix length.
* @returns true if it is valid otherwise false.
*/
-bool isValidPrefix(int addressFamily, uint8_t prefixLength);
+template <int family>
+constexpr bool isValidPrefix(uint8_t prefix) noexcept
+{
+ return prefix <= sizeof(typename FamilyTraits<family>::addr) * 8;
+}
+bool isValidPrefix(int family, uint8_t prefixLength);
/** @brief Get all the interfaces from the system.
* @returns list of interface names.
diff --git a/test/test_util.cpp b/test/test_util.cpp
index 677b3f6..5d05ffd 100644
--- a/test/test_util.cpp
+++ b/test/test_util.cpp
@@ -5,6 +5,7 @@
#include <cstddef>
#include <cstring>
+#include <stdexcept>
#include <stdplus/raw.hpp>
#include <string>
#include <string_view>
@@ -108,23 +109,21 @@
TEST_F(TestUtil, PrefixValidation)
{
- uint8_t prefixLength = 1;
- EXPECT_EQ(true, isValidPrefix(AF_INET, prefixLength));
+ EXPECT_TRUE(isValidPrefix(AF_INET, 0));
+ EXPECT_TRUE(isValidPrefix(AF_INET, 1));
+ EXPECT_TRUE(isValidPrefix(AF_INET, 32));
+ EXPECT_FALSE(isValidPrefix(AF_INET, 33));
+ EXPECT_FALSE(isValidPrefix(AF_INET, 64));
- prefixLength = 32;
- EXPECT_EQ(true, isValidPrefix(AF_INET, prefixLength));
+ EXPECT_TRUE(isValidPrefix(AF_INET6, 0));
+ EXPECT_TRUE(isValidPrefix(AF_INET6, 1));
+ EXPECT_TRUE(isValidPrefix(AF_INET6, 53));
+ EXPECT_TRUE(isValidPrefix(AF_INET6, 64));
+ EXPECT_TRUE(isValidPrefix(AF_INET6, 128));
+ EXPECT_FALSE(isValidPrefix(AF_INET6, 129));
+ EXPECT_FALSE(isValidPrefix(AF_INET6, 177));
- prefixLength = 0;
- EXPECT_EQ(false, isValidPrefix(AF_INET, prefixLength));
-
- prefixLength = 33;
- EXPECT_EQ(false, isValidPrefix(AF_INET, prefixLength));
-
- prefixLength = 33;
- EXPECT_EQ(true, isValidPrefix(AF_INET6, prefixLength));
-
- prefixLength = 65;
- EXPECT_EQ(false, isValidPrefix(AF_INET, prefixLength));
+ EXPECT_THROW(isValidPrefix(AF_UNSPEC, 1), std::invalid_argument);
}
TEST_F(TestUtil, InterfaceToUbootEthAddr)