1 #include "mock_network_manager.hpp"
2 #include "mock_syscall.hpp"
3 #include "rtnetlink_server.hpp"
4 #include "types.hpp"
5 
6 #include <linux/rtnetlink.h>
7 #include <net/if.h>
8 
9 #include <chrono>
10 #include <functional>
11 #include <sdbusplus/bus.hpp>
12 #include <sdeventplus/event.hpp>
13 #include <testutil.hpp>
14 
15 #include <gtest/gtest.h>
16 
17 namespace phosphor
18 {
19 
20 namespace network
21 {
22 sdbusplus::bus_t bus(sdbusplus::bus::new_default());
23 extern std::unique_ptr<MockManager> manager;
24 extern std::unique_ptr<Timer> refreshObjectTimer;
25 EventPtr eventPtr = nullptr;
26 
27 class TestRtNetlink : public TestWithTmp
28 {
29 
30   public:
31     std::optional<rtnetlink::Server> svr;
32 
33     TestRtNetlink()
34     {
35         manager = std::make_unique<MockManager>(bus, "/xyz/openbmc_test/bcd",
36                                                 CaseTmpDir());
37         sd_event* events;
38         sd_event_default(&events);
39         eventPtr.reset(events);
40         events = nullptr;
41         initializeTimers();
42         createNetLinkSocket();
43         bus.attach_event(eventPtr.get(), SD_EVENT_PRIORITY_NORMAL);
44         svr.emplace(eventPtr);
45     }
46 
47     void createNetLinkSocket()
48     {
49         // RtnetLink socket
50         auto fd = socket(PF_NETLINK, SOCK_RAW | SOCK_NONBLOCK, NETLINK_ROUTE);
51         smartSock.set(fd);
52     }
53 };
54 
55 TEST_F(TestRtNetlink, WithSingleInterface)
56 {
57     using namespace std::chrono;
58     mock_clear();
59     // Adds the following ip in the getifaddrs list.
60     mock_addIF("igb5", 6);
61     mock_addIP("igb5", "127.0.0.1", "255.255.255.128", IFF_UP | IFF_RUNNING);
62     constexpr auto BUFSIZE = 4096;
63     std::array<char, BUFSIZE> msgBuf = {0};
64 
65     // point the header and the msg structure pointers into the buffer.
66     auto nlMsg = reinterpret_cast<nlmsghdr*>(msgBuf.data());
67     // Length of message
68     nlMsg->nlmsg_len = NLMSG_LENGTH(sizeof(rtmsg));
69     nlMsg->nlmsg_type = RTM_GETADDR;
70     nlMsg->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST;
71     nlMsg->nlmsg_seq = 0;
72     nlMsg->nlmsg_pid = getpid();
73 
74     EXPECT_EQ(false, manager->hasInterface("igb5"));
75     // Send the request
76     send(svr->getSock(), nlMsg, nlMsg->nlmsg_len, 0);
77 
78     int i = 3;
79     while (i--)
80     {
81         // wait for timer to expire
82         std::this_thread::sleep_for(std::chrono::milliseconds(refreshTimeout));
83         sd_event_run(eventPtr.get(), 10);
84     };
85 
86     EXPECT_EQ(true, manager->hasInterface("igb5"));
87 }
88 
89 } // namespace network
90 } // namespace phosphor
91