xref: /openbmc/phosphor-networkd/test/test_rtnetlink.cpp (revision a84269022678260112d508424f5aeb617ceb3c88)
1 #include "rtnetlink.hpp"
2 
3 #include <linux/netlink.h>
4 #include <linux/rtnetlink.h>
5 
6 #include <stdplus/raw.hpp>
7 
8 #include <gtest/gtest.h>
9 
10 namespace phosphor::network::netlink
11 {
12 
13 TEST(AddrFromRtm, MissingAddr)
14 {
15     struct
16     {
17         alignas(NLMSG_ALIGNTO) ifaddrmsg ifa = {};
18     } msg;
19     EXPECT_THROW(addrFromRtm(stdplus::raw::asView<char>(msg)),
20                  std::runtime_error);
21 }
22 
23 TEST(AddrFromRtm, Regular)
24 {
25     struct
26     {
27         alignas(NLMSG_ALIGNTO) ifaddrmsg ifa;
28         alignas(NLMSG_ALIGNTO) rtattr addr_hdr;
29         alignas(NLMSG_ALIGNTO) uint8_t addr[4] = {192, 168, 1, 20};
30     } msg;
31     msg.ifa.ifa_family = AF_INET;
32     msg.ifa.ifa_prefixlen = 28;
33     msg.ifa.ifa_flags = 4;
34     msg.ifa.ifa_scope = 3;
35     msg.ifa.ifa_index = 10;
36     msg.addr_hdr.rta_type = IFA_ADDRESS;
37     msg.addr_hdr.rta_len = RTA_LENGTH(sizeof(msg.addr));
38 
39     auto ret = addrFromRtm(stdplus::raw::asView<char>(msg));
40     EXPECT_EQ(msg.ifa.ifa_flags, ret.flags);
41     EXPECT_EQ(msg.ifa.ifa_scope, ret.scope);
42     EXPECT_EQ(msg.ifa.ifa_index, ret.ifidx);
43     EXPECT_EQ((IfAddr{in_addr{hton(0xc0a80114)}, 28}), ret.ifaddr);
44 }
45 
46 TEST(AddrFromRtm, ExtraFlags)
47 {
48     struct
49     {
50         alignas(NLMSG_ALIGNTO) ifaddrmsg ifa = {};
51         alignas(NLMSG_ALIGNTO) rtattr flags_hdr;
52         alignas(NLMSG_ALIGNTO) uint32_t flags = 0xff00ff00;
53         alignas(NLMSG_ALIGNTO) rtattr addr_hdr;
54         alignas(NLMSG_ALIGNTO) uint8_t addr[16] = {};
55     } msg;
56     msg.ifa.ifa_family = AF_INET6;
57     msg.flags_hdr.rta_type = IFA_FLAGS;
58     msg.flags_hdr.rta_len = RTA_LENGTH(sizeof(msg.flags));
59     msg.addr_hdr.rta_type = IFA_ADDRESS;
60     msg.addr_hdr.rta_len = RTA_LENGTH(sizeof(msg.addr));
61 
62     auto ret = addrFromRtm(stdplus::raw::asView<char>(msg));
63     EXPECT_EQ(0xff00ff00, ret.flags);
64 }
65 
66 TEST(NeighFromRtm, MissingAddr)
67 {
68     struct
69     {
70         alignas(NLMSG_ALIGNTO) ndmsg ndm = {};
71     } msg;
72     EXPECT_THROW(neighFromRtm(stdplus::raw::asView<char>(msg)),
73                  std::runtime_error);
74 }
75 
76 TEST(NeighFromRtm, NoMac)
77 {
78     struct
79     {
80         alignas(NLMSG_ALIGNTO) ndmsg ndm;
81         alignas(NLMSG_ALIGNTO) rtattr addr_hdr;
82         alignas(NLMSG_ALIGNTO) uint8_t addr[4] = {192, 168, 1, 20};
83     } msg;
84     msg.ndm.ndm_family = AF_INET;
85     msg.ndm.ndm_state = 4;
86     msg.addr_hdr.rta_type = NDA_DST;
87     msg.addr_hdr.rta_len = RTA_LENGTH(sizeof(msg.addr));
88 
89     auto ret = neighFromRtm(stdplus::raw::asView<char>(msg));
90     EXPECT_EQ(msg.ndm.ndm_state, ret.state);
91     EXPECT_EQ((in_addr{hton(0xc0a80114)}), ret.addr);
92     EXPECT_FALSE(ret.mac);
93 }
94 
95 TEST(NeighFromRtm, Full)
96 {
97     struct
98     {
99         alignas(NLMSG_ALIGNTO) ndmsg ndm;
100         alignas(NLMSG_ALIGNTO) rtattr addr_hdr;
101         alignas(NLMSG_ALIGNTO) uint8_t addr[4] = {192, 168, 1, 20};
102         alignas(NLMSG_ALIGNTO) rtattr mac_hdr;
103         alignas(NLMSG_ALIGNTO) uint8_t mac[6] = {1, 2, 3, 4, 5, 6};
104     } msg;
105     msg.ndm.ndm_family = AF_INET;
106     msg.addr_hdr.rta_type = NDA_DST;
107     msg.addr_hdr.rta_len = RTA_LENGTH(sizeof(msg.addr));
108     msg.mac_hdr.rta_type = NDA_LLADDR;
109     msg.mac_hdr.rta_len = RTA_LENGTH(sizeof(msg.mac));
110 
111     auto ret = neighFromRtm(stdplus::raw::asView<char>(msg));
112     EXPECT_EQ((in_addr{hton(0xc0a80114)}), ret.addr);
113     EXPECT_EQ((ether_addr{1, 2, 3, 4, 5, 6}), ret.mac);
114 }
115 
116 } // namespace phosphor::network::netlink
117