blob: d5de216da00c3a315770b8f873c37ec8d55b8a58 [file] [log] [blame]
#include "rtnetlink.hpp"
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <stdplus/raw.hpp>
#include <gtest/gtest.h>
namespace phosphor::network::netlink
{
TEST(IntfFromRtm, SmallMsg)
{
EXPECT_THROW(intfFromRtm("1"), std::runtime_error);
}
TEST(IntfFromRtm, NoAttrs)
{
struct
{
ifinfomsg hdr __attribute__((aligned(NLMSG_ALIGNTO)));
} msg;
msg.hdr.ifi_type = 3;
msg.hdr.ifi_index = 1;
msg.hdr.ifi_flags = 2;
EXPECT_EQ(intfFromRtm(stdplus::raw::asView<char>(msg)),
(InterfaceInfo{.type = 3, .idx = 1, .flags = 2}));
}
TEST(IntfFromRtm, AllAttrs)
{
struct
{
ifinfomsg hdr __attribute__((aligned(NLMSG_ALIGNTO)));
rtattr addr_hdr __attribute__((aligned((RTA_ALIGNTO))));
char addr[6]
__attribute__((aligned((RTA_ALIGNTO)))) = {0, 1, 2, 3, 4, 5};
rtattr name_hdr __attribute__((aligned((RTA_ALIGNTO))));
char name[5] __attribute__((aligned((RTA_ALIGNTO)))) = "eth0";
rtattr mtu_hdr __attribute__((aligned((RTA_ALIGNTO))));
unsigned mtu __attribute__((aligned((RTA_ALIGNTO)))) = 50;
} msg;
msg.hdr.ifi_type = 4;
msg.hdr.ifi_index = 1;
msg.hdr.ifi_flags = 2;
msg.addr_hdr.rta_type = IFLA_ADDRESS;
msg.addr_hdr.rta_len = RTA_LENGTH(sizeof(msg.addr));
msg.name_hdr.rta_type = IFLA_IFNAME;
msg.name_hdr.rta_len = RTA_LENGTH(sizeof(msg.name));
msg.mtu_hdr.rta_type = IFLA_MTU;
msg.mtu_hdr.rta_len = RTA_LENGTH(sizeof(msg.mtu));
auto info = intfFromRtm(stdplus::raw::asView<char>(msg));
auto expected = InterfaceInfo{.type = 4,
.idx = 1,
.flags = 2,
.name = "eth0",
.mac = ether_addr{0, 1, 2, 3, 4, 5},
.mtu = 50};
EXPECT_EQ(info, expected);
}
TEST(AddrFromRtm, MissingAddr)
{
struct
{
alignas(NLMSG_ALIGNTO) ifaddrmsg ifa = {};
} msg;
EXPECT_THROW(addrFromRtm(stdplus::raw::asView<char>(msg)),
std::runtime_error);
}
TEST(AddrFromRtm, Regular)
{
struct
{
alignas(NLMSG_ALIGNTO) ifaddrmsg ifa;
alignas(NLMSG_ALIGNTO) rtattr addr_hdr;
alignas(NLMSG_ALIGNTO) uint8_t addr[4] = {192, 168, 1, 20};
} msg;
msg.ifa.ifa_family = AF_INET;
msg.ifa.ifa_prefixlen = 28;
msg.ifa.ifa_flags = 4;
msg.ifa.ifa_scope = 3;
msg.ifa.ifa_index = 10;
msg.addr_hdr.rta_type = IFA_ADDRESS;
msg.addr_hdr.rta_len = RTA_LENGTH(sizeof(msg.addr));
auto ret = addrFromRtm(stdplus::raw::asView<char>(msg));
EXPECT_EQ(msg.ifa.ifa_flags, ret.flags);
EXPECT_EQ(msg.ifa.ifa_scope, ret.scope);
EXPECT_EQ(msg.ifa.ifa_index, ret.ifidx);
EXPECT_EQ((IfAddr{in_addr{stdplus::hton(0xc0a80114)}, 28}), ret.ifaddr);
}
TEST(AddrFromRtm, ExtraFlags)
{
struct
{
alignas(NLMSG_ALIGNTO) ifaddrmsg ifa = {};
alignas(NLMSG_ALIGNTO) rtattr flags_hdr;
alignas(NLMSG_ALIGNTO) uint32_t flags = 0xff00ff00;
alignas(NLMSG_ALIGNTO) rtattr addr_hdr;
alignas(NLMSG_ALIGNTO) uint8_t addr[16] = {};
} msg;
msg.ifa.ifa_family = AF_INET6;
msg.flags_hdr.rta_type = IFA_FLAGS;
msg.flags_hdr.rta_len = RTA_LENGTH(sizeof(msg.flags));
msg.addr_hdr.rta_type = IFA_ADDRESS;
msg.addr_hdr.rta_len = RTA_LENGTH(sizeof(msg.addr));
auto ret = addrFromRtm(stdplus::raw::asView<char>(msg));
EXPECT_EQ(0xff00ff00, ret.flags);
}
TEST(NeighFromRtm, MissingAddr)
{
struct
{
alignas(NLMSG_ALIGNTO) ndmsg ndm = {};
} msg;
EXPECT_EQ((NeighborInfo{}), neighFromRtm(stdplus::raw::asView<char>(msg)));
}
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{stdplus::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{stdplus::hton(0xc0a80114)}), ret.addr);
EXPECT_EQ((ether_addr{1, 2, 3, 4, 5, 6}), ret.mac);
}
} // namespace phosphor::network::netlink