diff options
author | Nagaraju Goruganti <ngorugan@in.ibm.com> | 2017-10-03 08:43:08 -0500 |
---|---|---|
committer | Brad Bishop <bradleyb@fuzziesquirrel.com> | 2017-10-11 23:16:31 +0000 |
commit | 66b974d2d679ece3aa67032bbc13ac166702cede (patch) | |
tree | 4c31f2c253a8b2d289aad27970a31e0a13611d03 | |
parent | c9645fe5c874930445bca6ba51ac9daee916c99b (diff) | |
download | phosphor-networkd-66b974d2d679ece3aa67032bbc13ac166702cede.tar.gz phosphor-networkd-66b974d2d679ece3aa67032bbc13ac166702cede.zip |
IP Address use case validation
-validates IPAddress/gateway using inet_pton api.
-validates prefix length for ipv4/ipv6.
-if dhcp is enabled, it won't allow to set ip/gateway.
Resolves openbmc/openbmc#1671
Change-Id: I76c1d9d11dfb59002eb1310d87e94ee622714a4a
Signed-off-by: Nagaraju Goruganti <ngorugan@in.ibm.com>
-rw-r--r-- | ethernet_interface.cpp | 37 | ||||
-rw-r--r-- | ipaddress.cpp | 19 | ||||
-rw-r--r-- | test/test_util.cpp | 17 | ||||
-rw-r--r-- | util.cpp | 37 | ||||
-rw-r--r-- | util.hpp | 23 |
5 files changed, 120 insertions, 13 deletions
diff --git a/ethernet_interface.cpp b/ethernet_interface.cpp index ffaac74..5a7c61c 100644 --- a/ethernet_interface.cpp +++ b/ethernet_interface.cpp @@ -33,6 +33,7 @@ namespace network using namespace phosphor::logging; using namespace sdbusplus::xyz::openbmc_project::Common::Error; +using Argument = xyz::openbmc_project::Common::InvalidArgument; EthernetInterface::EthernetInterface(sdbusplus::bus::bus& bus, const std::string& objPath, @@ -78,7 +79,7 @@ void EthernetInterface::createIPAddressObjects() { origin = IP::AddressOrigin::DHCP; } - else if (isLinkLocal(addr.ipaddress)) + else if (isLinkLocalIP(addr.ipaddress)) { origin = IP::AddressOrigin::LinkLocal; } @@ -113,12 +114,42 @@ void EthernetInterface::iP(IP::Protocol protType, if (dHCPEnabled()) { log<level::INFO>("DHCP enabled on the interface"), - entry("INTERFACE=%s",interfaceName().c_str()); - return; + entry("INTERFACE=%s", interfaceName().c_str()); + dHCPEnabled(false); } + IP::AddressOrigin origin = IP::AddressOrigin::Static; + int addressFamily = (protType == IP::Protocol::IPv4) ? AF_INET : AF_INET6; + + if (!isValidIP(addressFamily, ipaddress)) + { + log<level::ERR>("Not a valid IP address"), + entry("ADDRESS=%s", ipaddress.c_str()); + elog<InvalidArgument>(Argument::ARGUMENT_NAME("ipaddress"), + Argument::ARGUMENT_VALUE(ipaddress.c_str())); + } + + if (!gateway.empty() && (!isValidIP(addressFamily, gateway))) + { + log<level::ERR>("Not a valid Gateway"), + entry("GATEWAY=%s", gateway.c_str()); + elog<InvalidArgument>(Argument::ARGUMENT_NAME("gateway"), + Argument::ARGUMENT_VALUE(gateway.c_str())); + } + + if (!isValidPrefix(addressFamily, prefixLength)) + { + log<level::ERR>("PrefixLength is not correct "), + entry("PREFIXLENGTH=%d", gateway.c_str()); + elog<InvalidArgument>(Argument::ARGUMENT_NAME("prefixLength"), + Argument::ARGUMENT_VALUE(std::to_string( + prefixLength).c_str())); + return; + } + + std::string objectPath = generateObjectPath(protType, ipaddress, prefixLength, diff --git a/ipaddress.cpp b/ipaddress.cpp index b2407ef..4daccd5 100644 --- a/ipaddress.cpp +++ b/ipaddress.cpp @@ -1,7 +1,10 @@ #include "ipaddress.hpp" #include "ethernet_interface.hpp" +#include "util.hpp" +#include "xyz/openbmc_project/Common/error.hpp" #include <phosphor-logging/log.hpp> +#include <phosphor-logging/elog-errors.hpp> namespace phosphor { @@ -9,6 +12,7 @@ namespace network { using namespace phosphor::logging; +using namespace sdbusplus::xyz::openbmc_project::Common::Error; IPAddress::IPAddress(sdbusplus::bus::bus& bus, const char* objPath, @@ -34,6 +38,21 @@ IPAddress::IPAddress(sdbusplus::bus::bus& bus, void IPAddress::delete_() { + if (parent.dHCPEnabled()) + { + log<level::ERR>("DHCP enabled on the interface"), + entry("INTERFACE=%s", parent.interfaceName().c_str()); + elog<InternalFailure>(); + } + + if (isLinkLocalIP(address())) + { + log<level::ERR>("Can not delete the LinkLocal address"), + entry("INTERFACE=%s ADDRESS=%s", + parent.interfaceName().c_str(), address().c_str()); + elog<InternalFailure>(); + } + parent.deleteObject(address()); } diff --git a/test/test_util.cpp b/test/test_util.cpp index 9b1d34a..1c78b64 100644 --- a/test/test_util.cpp +++ b/test/test_util.cpp @@ -64,13 +64,22 @@ TEST_F(TestUtil, convertV6MasktoPrefix) TEST_F(TestUtil, isLinkLocaladdress) { std::string ipaddress = "fe80:fec0::"; - EXPECT_TRUE(isLinkLocal(ipaddress)); + EXPECT_TRUE(isLinkLocalIP(ipaddress)); - ipaddress = "2000:4567:789::"; - EXPECT_FALSE(isLinkLocal(ipaddress)); + ipaddress = "2000:fe80:789::"; + EXPECT_FALSE(isLinkLocalIP(ipaddress)); ipaddress = "2000:fe80::"; - EXPECT_FALSE(isLinkLocal(ipaddress)); + EXPECT_FALSE(isLinkLocalIP(ipaddress)); + + ipaddress = "169.254.3.3"; + EXPECT_TRUE(isLinkLocalIP(ipaddress)); + + ipaddress = "3.169.254.3"; + EXPECT_FALSE(isLinkLocalIP(ipaddress)); + + ipaddress = "3.3.169.254"; + EXPECT_FALSE(isLinkLocalIP(ipaddress)); } TEST_F(TestUtil, convertPrefixToMask) @@ -202,12 +202,39 @@ std::string getNetworkID(int addressFamily, const std::string& ipaddress, return networkString; } -bool isLinkLocal(const std::string& address) +bool isLinkLocalIP(const std::string& address) { - std::string linklocal = "fe80"; - return std::mismatch(linklocal.begin(), linklocal.end(), - address.begin()).first == linklocal.end() ? - true : false; + return address.find(IPV4_PREFIX) == 0 || address.find(IPV6_PREFIX) == 0; +} + +bool isValidIP(int addressFamily, const std::string& address) +{ + unsigned char buf[sizeof(struct in6_addr)]; + + return inet_pton(addressFamily, address.c_str(), buf) > 0; +} + +bool isValidPrefix(int addressFamily, uint8_t prefixLength) +{ + 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; } IntfAddrMap getInterfaceAddrs() @@ -11,6 +11,13 @@ namespace phosphor { namespace network { + +constexpr auto IPV4_MIN_PREFIX_LENGTH = 1; +constexpr auto IPV4_MAX_PREFIX_LENGTH = 32; +constexpr auto IPV6_MAX_PREFIX_LENGTH = 64; +constexpr auto IPV4_PREFIX = "169.254"; +constexpr auto IPV6_PREFIX = "fe80"; + namespace mac_address { @@ -81,7 +88,21 @@ std::string toMask(int addressFamily, uint8_t prefix); * @param[in] address - IP address. * @returns true if it is linklocal otherwise false. */ -bool isLinkLocal(const std::string& address); +bool isLinkLocalIP(const std::string& address); + +/* @brief checks that the given ip address valid or not. + * @param[in] addressFamily - IP address family(AF_INET/AF_INET6). + * @param[in] address - IP address. + * @returns true if it is valid otherwise false. + */ +bool isValidIP(int addressFamily, const std::string& address); + +/* @brief checks that the given prefix is valid or not. + * @param[in] addressFamily - 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); /* @brief gets the network section of the ip adress. * @param[in] addressFamily - IP address family(AF_INET/AF_INET6). |