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 
14 #include <gtest/gtest.h>
15 
16 namespace phosphor
17 {
18 
19 namespace network
20 {
21 sdbusplus::bus::bus bus(sdbusplus::bus::new_default());
22 extern std::unique_ptr<MockManager> manager;
23 extern std::unique_ptr<Timer> refreshObjectTimer;
24 extern std::unique_ptr<Timer> restartTimer;
25 EventPtr eventPtr = nullptr;
26 
27 class TestRtNetlink : public testing::Test
28 {
29 
30   public:
31     std::string confDir;
32     phosphor::Descriptor smartSock;
33 
34     TestRtNetlink()
35     {
36         manager =
37             std::make_unique<MockManager>(bus, "/xyz/openbmc_test/bcd", "/tmp");
38         sd_event* events;
39         sd_event_default(&events);
40         eventPtr.reset(events);
41         events = nullptr;
42         setConfDir();
43         initializeTimers();
44         createNetLinkSocket();
45         bus.attach_event(eventPtr.get(), SD_EVENT_PRIORITY_NORMAL);
46         rtnetlink::Server svr(eventPtr, smartSock);
47     }
48 
49     ~TestRtNetlink()
50     {
51         if (confDir.empty())
52         {
53             fs::remove_all(confDir);
54         }
55     }
56 
57     void setConfDir()
58     {
59         char tmp[] = "/tmp/NetworkManager.XXXXXX";
60         confDir = mkdtemp(tmp);
61         manager->setConfDir(confDir);
62     }
63 
64     void createNetLinkSocket()
65     {
66         // RtnetLink socket
67         auto fd = socket(PF_NETLINK, SOCK_RAW | SOCK_NONBLOCK, NETLINK_ROUTE);
68         smartSock.set(fd);
69     }
70 };
71 
72 TEST_F(TestRtNetlink, WithSingleInterface)
73 {
74     using namespace std::chrono;
75     mock_clear();
76     // Adds the following ip in the getifaddrs list.
77     mock_addIF("igb5", 6);
78     mock_addIP("igb5", "127.0.0.1", "255.255.255.128", IFF_UP | IFF_RUNNING);
79     constexpr auto BUFSIZE = 4096;
80     std::array<char, BUFSIZE> msgBuf = {0};
81 
82     // point the header and the msg structure pointers into the buffer.
83     auto nlMsg = reinterpret_cast<nlmsghdr*>(msgBuf.data());
84     // Length of message
85     nlMsg->nlmsg_len = NLMSG_LENGTH(sizeof(rtmsg));
86     nlMsg->nlmsg_type = RTM_GETADDR;
87     nlMsg->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST;
88     nlMsg->nlmsg_seq = 0;
89     nlMsg->nlmsg_pid = getpid();
90 
91     EXPECT_EQ(false, manager->hasInterface("igb5"));
92     // Send the request
93     send(smartSock(), nlMsg, nlMsg->nlmsg_len, 0);
94 
95     int i = 3;
96     while (i--)
97     {
98         // wait for timer to expire
99         std::this_thread::sleep_for(std::chrono::milliseconds(refreshTimeout));
100         sd_event_run(eventPtr.get(), 10);
101     };
102 
103     EXPECT_EQ(true, manager->hasInterface("igb5"));
104 }
105 
106 } // namespace network
107 } // namespace phosphor
108