rtnetlink: Migrate neighbor functions
Change-Id: I697f3d70f327f5d1d5e104dc7e4a2af528bf2b6e
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/test/meson.build b/test/meson.build
index 6a46c1d..22bbfe3 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -46,7 +46,6 @@
tests = [
'config_parser',
'ethernet_interface',
- 'neighbor',
'netlink',
'network_manager',
'rtnetlink',
diff --git a/test/test_neighbor.cpp b/test/test_neighbor.cpp
deleted file mode 100644
index 3cdb209..0000000
--- a/test/test_neighbor.cpp
+++ /dev/null
@@ -1,239 +0,0 @@
-#include "neighbor.hpp"
-#include "util.hpp"
-
-#include <arpa/inet.h>
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>
-#include <net/ethernet.h>
-
-#include <cstring>
-#include <stdexcept>
-#include <string>
-#include <vector>
-
-#include <gtest/gtest.h>
-
-namespace phosphor
-{
-namespace network
-{
-namespace detail
-{
-
-TEST(ParseNeighbor, NotNeighborType)
-{
- nlmsghdr hdr{};
- hdr.nlmsg_type = RTM_NEWLINK;
- NeighborFilter filter;
-
- std::vector<NeighborInfo> neighbors;
- EXPECT_THROW(parseNeighbor(filter, hdr, "", neighbors), std::runtime_error);
- EXPECT_EQ(0, neighbors.size());
-}
-
-TEST(ParseNeighbor, SmallMsg)
-{
- nlmsghdr hdr{};
- hdr.nlmsg_type = RTM_NEWNEIGH;
- std::string data = "1";
- NeighborFilter filter;
-
- std::vector<NeighborInfo> neighbors;
- EXPECT_THROW(parseNeighbor(filter, hdr, data, neighbors),
- std::runtime_error);
- EXPECT_EQ(0, neighbors.size());
-}
-
-TEST(ParseNeighbor, NoAttrs)
-{
- nlmsghdr hdr{};
- hdr.nlmsg_type = RTM_NEWNEIGH;
- ndmsg msg{};
- msg.ndm_ifindex = 1;
- msg.ndm_state = NUD_REACHABLE;
- std::string data;
- data.append(reinterpret_cast<char*>(&msg), sizeof(msg));
- NeighborFilter filter;
-
- std::vector<NeighborInfo> neighbors;
- EXPECT_THROW(parseNeighbor(filter, hdr, data, neighbors),
- std::runtime_error);
- EXPECT_EQ(0, neighbors.size());
-}
-
-TEST(ParseNeighbor, NoAddress)
-{
- nlmsghdr hdr{};
- hdr.nlmsg_type = RTM_NEWNEIGH;
- ndmsg msg{};
- msg.ndm_ifindex = 1;
- msg.ndm_state = NUD_REACHABLE;
- ether_addr mac = {{0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa}};
- rtattr lladdr{};
- constexpr size_t len = RTA_LENGTH(sizeof(mac));
- lladdr.rta_len = len;
- lladdr.rta_type = NDA_LLADDR;
- char lladdrbuf[RTA_ALIGN(len)];
- std::memset(lladdrbuf, '\0', sizeof(lladdrbuf));
- std::memcpy(lladdrbuf, &lladdr, sizeof(lladdr));
- std::memcpy(RTA_DATA(lladdrbuf), &mac, sizeof(mac));
- std::string data;
- data.append(reinterpret_cast<char*>(&msg), sizeof(msg));
- data.append(reinterpret_cast<char*>(&lladdrbuf), sizeof(lladdrbuf));
- NeighborFilter filter;
-
- std::vector<NeighborInfo> neighbors;
- EXPECT_THROW(parseNeighbor(filter, hdr, data, neighbors),
- std::runtime_error);
- EXPECT_EQ(0, neighbors.size());
-}
-
-TEST(ParseNeighbor, NoMAC)
-{
- nlmsghdr hdr{};
- hdr.nlmsg_type = RTM_NEWNEIGH;
- ndmsg msg{};
- msg.ndm_family = AF_INET;
- msg.ndm_state = NUD_PERMANENT;
- msg.ndm_ifindex = 1;
- in_addr addr;
- ASSERT_EQ(1, inet_pton(msg.ndm_family, "192.168.10.1", &addr));
- rtattr dst{};
- constexpr size_t len = RTA_LENGTH(sizeof(addr));
- dst.rta_len = len;
- dst.rta_type = NDA_DST;
- char dstbuf[RTA_ALIGN(len)];
- std::memset(dstbuf, '\0', sizeof(dstbuf));
- std::memcpy(dstbuf, &dst, sizeof(dst));
- std::memcpy(RTA_DATA(dstbuf), &addr, sizeof(addr));
- std::string data;
- data.append(reinterpret_cast<char*>(&msg), sizeof(msg));
- data.append(reinterpret_cast<char*>(&dstbuf), sizeof(dstbuf));
- NeighborFilter filter;
-
- std::vector<NeighborInfo> neighbors;
- parseNeighbor(filter, hdr, data, neighbors);
- EXPECT_EQ(1, neighbors.size());
- EXPECT_EQ(msg.ndm_ifindex, neighbors[0].interface);
- EXPECT_EQ(msg.ndm_state, neighbors[0].state);
- EXPECT_FALSE(neighbors[0].mac);
- EXPECT_EQ(addr, neighbors[0].address);
-}
-
-TEST(ParseNeighbor, FilterInterface)
-{
- nlmsghdr hdr{};
- hdr.nlmsg_type = RTM_NEWNEIGH;
- ndmsg msg{};
- msg.ndm_family = AF_INET;
- msg.ndm_state = NUD_PERMANENT;
- msg.ndm_ifindex = 2;
- in_addr addr;
- ASSERT_EQ(1, inet_pton(msg.ndm_family, "192.168.10.1", &addr));
- rtattr dst{};
- constexpr size_t len = RTA_LENGTH(sizeof(addr));
- dst.rta_len = len;
- dst.rta_type = NDA_DST;
- char dstbuf[RTA_ALIGN(len)];
- std::memset(dstbuf, '\0', sizeof(dstbuf));
- std::memcpy(dstbuf, &dst, sizeof(dst));
- std::memcpy(RTA_DATA(dstbuf), &addr, sizeof(addr));
- std::string data;
- data.append(reinterpret_cast<char*>(&msg), sizeof(msg));
- data.append(reinterpret_cast<char*>(&dstbuf), sizeof(dstbuf));
- NeighborFilter filter;
-
- std::vector<NeighborInfo> neighbors;
- filter.interface = 1;
- parseNeighbor(filter, hdr, data, neighbors);
- EXPECT_EQ(0, neighbors.size());
- filter.interface = 2;
- parseNeighbor(filter, hdr, data, neighbors);
- EXPECT_EQ(1, neighbors.size());
- EXPECT_EQ(msg.ndm_ifindex, neighbors[0].interface);
- EXPECT_EQ(msg.ndm_state, neighbors[0].state);
- EXPECT_FALSE(neighbors[0].mac);
- EXPECT_EQ(addr, neighbors[0].address);
-}
-
-TEST(ParseNeighbor, FilterState)
-{
- nlmsghdr hdr{};
- hdr.nlmsg_type = RTM_NEWNEIGH;
- ndmsg msg{};
- msg.ndm_family = AF_INET;
- msg.ndm_state = NUD_PERMANENT;
- msg.ndm_ifindex = 2;
- in_addr addr;
- ASSERT_EQ(1, inet_pton(msg.ndm_family, "192.168.10.1", &addr));
- rtattr dst{};
- constexpr size_t len = RTA_LENGTH(sizeof(addr));
- dst.rta_len = len;
- dst.rta_type = NDA_DST;
- char dstbuf[RTA_ALIGN(len)];
- std::memset(dstbuf, '\0', sizeof(dstbuf));
- std::memcpy(dstbuf, &dst, sizeof(dst));
- std::memcpy(RTA_DATA(dstbuf), &addr, sizeof(addr));
- std::string data;
- data.append(reinterpret_cast<char*>(&msg), sizeof(msg));
- data.append(reinterpret_cast<char*>(&dstbuf), sizeof(dstbuf));
- NeighborFilter filter;
-
- std::vector<NeighborInfo> neighbors;
- filter.state = NUD_NOARP;
- parseNeighbor(filter, hdr, data, neighbors);
- EXPECT_EQ(0, neighbors.size());
- filter.state = NUD_PERMANENT | NUD_NOARP;
- parseNeighbor(filter, hdr, data, neighbors);
- EXPECT_EQ(1, neighbors.size());
- EXPECT_EQ(msg.ndm_ifindex, neighbors[0].interface);
- EXPECT_EQ(msg.ndm_state, neighbors[0].state);
- EXPECT_FALSE(neighbors[0].mac);
- EXPECT_EQ(addr, neighbors[0].address);
-}
-
-TEST(ParseNeighbor, Full)
-{
- nlmsghdr hdr{};
- hdr.nlmsg_type = RTM_NEWNEIGH;
- ndmsg msg{};
- msg.ndm_family = AF_INET6;
- msg.ndm_state = NUD_NOARP;
- msg.ndm_ifindex = 1;
- ether_addr mac = {{0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa}};
- rtattr lladdr{};
- constexpr size_t lladdr_len = RTA_LENGTH(sizeof(mac));
- lladdr.rta_len = lladdr_len;
- lladdr.rta_type = NDA_LLADDR;
- char lladdrbuf[RTA_ALIGN(lladdr_len)];
- std::memset(lladdrbuf, '\0', sizeof(lladdrbuf));
- std::memcpy(lladdrbuf, &lladdr, sizeof(lladdr));
- std::memcpy(RTA_DATA(lladdrbuf), &mac, sizeof(mac));
- in6_addr addr;
- ASSERT_EQ(1, inet_pton(msg.ndm_family, "fd00::1", &addr));
- rtattr dst{};
- constexpr size_t dst_len = RTA_LENGTH(sizeof(addr));
- dst.rta_len = dst_len;
- dst.rta_type = NDA_DST;
- char dstbuf[RTA_ALIGN(dst_len)];
- std::memset(dstbuf, '\0', sizeof(dstbuf));
- std::memcpy(dstbuf, &dst, sizeof(dst));
- std::memcpy(RTA_DATA(dstbuf), &addr, sizeof(addr));
- std::string data;
- data.append(reinterpret_cast<char*>(&msg), sizeof(msg));
- data.append(reinterpret_cast<char*>(&lladdrbuf), sizeof(lladdrbuf));
- data.append(reinterpret_cast<char*>(&dstbuf), sizeof(dstbuf));
- NeighborFilter filter;
-
- std::vector<NeighborInfo> neighbors;
- parseNeighbor(filter, hdr, data, neighbors);
- EXPECT_EQ(1, neighbors.size());
- EXPECT_EQ(msg.ndm_ifindex, neighbors[0].interface);
- EXPECT_EQ(msg.ndm_state, neighbors[0].state);
- EXPECT_EQ(mac, neighbors[0].mac);
- EXPECT_EQ(addr, neighbors[0].address);
-}
-
-} // namespace detail
-} // namespace network
-} // namespace phosphor
diff --git a/test/test_rtnetlink.cpp b/test/test_rtnetlink.cpp
index 9518cdc..8bf2a1e 100644
--- a/test/test_rtnetlink.cpp
+++ b/test/test_rtnetlink.cpp
@@ -63,4 +63,54 @@
EXPECT_EQ(0xff00ff00, ret.flags);
}
+TEST(NeighFromRtm, MissingAddr)
+{
+ struct
+ {
+ alignas(NLMSG_ALIGNTO) ndmsg ndm = {};
+ } msg;
+ EXPECT_THROW(neighFromRtm(stdplus::raw::asView<char>(msg)),
+ std::runtime_error);
+}
+
+TEST(NeighFromRtm, NoMac)
+{
+ struct
+ {
+ alignas(NLMSG_ALIGNTO) ndmsg ndm;
+ alignas(NLMSG_ALIGNTO) rtattr addr_hdr;
+ alignas(NLMSG_ALIGNTO) uint8_t addr[4] = {192, 168, 1, 20};
+ } msg;
+ msg.ndm.ndm_family = AF_INET;
+ msg.ndm.ndm_state = 4;
+ msg.addr_hdr.rta_type = NDA_DST;
+ msg.addr_hdr.rta_len = RTA_LENGTH(sizeof(msg.addr));
+
+ auto ret = neighFromRtm(stdplus::raw::asView<char>(msg));
+ EXPECT_EQ(msg.ndm.ndm_state, ret.state);
+ EXPECT_EQ((in_addr{hton(0xc0a80114)}), ret.addr);
+ EXPECT_FALSE(ret.mac);
+}
+
+TEST(NeighFromRtm, Full)
+{
+ struct
+ {
+ alignas(NLMSG_ALIGNTO) ndmsg ndm;
+ alignas(NLMSG_ALIGNTO) rtattr addr_hdr;
+ alignas(NLMSG_ALIGNTO) uint8_t addr[4] = {192, 168, 1, 20};
+ alignas(NLMSG_ALIGNTO) rtattr mac_hdr;
+ alignas(NLMSG_ALIGNTO) uint8_t mac[6] = {1, 2, 3, 4, 5, 6};
+ } msg;
+ msg.ndm.ndm_family = AF_INET;
+ msg.addr_hdr.rta_type = NDA_DST;
+ msg.addr_hdr.rta_len = RTA_LENGTH(sizeof(msg.addr));
+ msg.mac_hdr.rta_type = NDA_LLADDR;
+ msg.mac_hdr.rta_len = RTA_LENGTH(sizeof(msg.mac));
+
+ auto ret = neighFromRtm(stdplus::raw::asView<char>(msg));
+ EXPECT_EQ((in_addr{hton(0xc0a80114)}), ret.addr);
+ EXPECT_EQ((ether_addr{1, 2, 3, 4, 5, 6}), ret.mac);
+}
+
} // namespace phosphor::network::netlink
diff --git a/test/test_system_queries.cpp b/test/test_system_queries.cpp
index 047d968..a79bc77 100644
--- a/test/test_system_queries.cpp
+++ b/test/test_system_queries.cpp
@@ -122,5 +122,16 @@
EXPECT_FALSE(validateNewAddr(info, {.ifidx = 3}));
}
+TEST(ValidateNewNeigh, Filtering)
+{
+ NeighborInfo info = {};
+ EXPECT_TRUE(validateNewNeigh(info, {}));
+
+ info.ifidx = 2;
+ EXPECT_TRUE(validateNewNeigh(info, {}));
+ EXPECT_TRUE(validateNewNeigh(info, {.ifidx = 2}));
+ EXPECT_FALSE(validateNewNeigh(info, {.ifidx = 3}));
+}
+
} // namespace detail
} // namespace phosphor::network::system