1 #include "types.hpp"
2 #include "rtnetlink_server.hpp"
3 #include "network_manager.hpp"
4 #include "mock_syscall.hpp"
5 #include "timer.hpp"
6 #include "types.hpp"
7 
8 
9 #include <gtest/gtest.h>
10 #include <sdbusplus/bus.hpp>
11 
12 #include <net/if.h>
13 #include <linux/rtnetlink.h>
14 
15 namespace phosphor
16 {
17 
18 namespace network
19 {
20 sdbusplus::bus::bus bus(sdbusplus::bus::new_default());
21 std::unique_ptr<Manager> manager = nullptr;
22 std::unique_ptr<Timer> refreshObjectTimer = nullptr;
23 std::unique_ptr<Timer> restartTimer = nullptr;
24 EventPtr eventPtr = nullptr;
25 
26 /** @brief refresh the network objects. */
27 void refreshObjects()
28 {
29 
30     if (manager)
31     {
32         manager->createChildObjects();
33     }
34 }
35 
36 void initializeTimers()
37 {
38     std::function<void()> refreshFunc(
39         std::bind(&refreshObjects));
40 
41     refreshObjectTimer =
42         std::make_unique<Timer>(refreshFunc);
43 
44 }
45 
46 class TestRtNetlink : public testing::Test
47 {
48 
49     public:
50         std::string confDir;
51         phosphor::Descriptor smartSock;
52 
53 
54 
55         TestRtNetlink()
56         {
57             manager =
58                 std::make_unique<Manager>(bus,
59                         "/xyz/openbmc_test/bcd",
60                         "/tmp");
61             sd_event* events;
62             sd_event_default(&events);
63             eventPtr.reset(events);
64             events = nullptr;
65             setConfDir();
66             initializeTimers();
67             createNetLinkSocket();
68             bus.attach_event(eventPtr.get(), SD_EVENT_PRIORITY_NORMAL);
69             rtnetlink::Server svr(eventPtr, smartSock);
70         }
71 
72         ~TestRtNetlink()
73         {
74             if (confDir.empty())
75             {
76                 fs::remove_all(confDir);
77             }
78         }
79 
80         void setConfDir()
81         {
82             confDir = "/tmp/NetworkManager.YYYY";
83             manager->setConfDir(confDir);
84         }
85 
86         bool isInterfaceAdded(std::string intf)
87         {
88             return manager->interfaces.find(intf) != manager->interfaces.end()?
89                    true :
90                    false;
91         }
92 
93         void createNetLinkSocket()
94         {
95             //RtnetLink socket
96             auto fd = socket(PF_NETLINK, SOCK_RAW | SOCK_NONBLOCK,
97                 NETLINK_ROUTE);
98             smartSock.set(fd);
99         }
100 };
101 
102 
103 TEST_F(TestRtNetlink, WithSingleInterface)
104 {
105     using namespace std::chrono;
106     // Adds the following ip in the getifaddrs list.
107     mock_addIP("igb5", "127.0.0.1", "255.255.255.128",
108                IFF_UP | IFF_RUNNING);
109     constexpr auto BUFSIZE = 4096;
110     std::array<char, BUFSIZE> msgBuf = {0};
111 
112     // point the header and the msg structure pointers into the buffer.
113     auto nlMsg = reinterpret_cast<nlmsghdr*>(msgBuf.data());
114     // Length of message
115     nlMsg->nlmsg_len = NLMSG_LENGTH(sizeof(rtmsg));
116     nlMsg->nlmsg_type = RTM_GETADDR;
117     nlMsg->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST;
118     nlMsg->nlmsg_seq = 0;
119     nlMsg->nlmsg_pid = getpid();
120 
121     EXPECT_EQ(false, isInterfaceAdded("igb5"));
122     // Send the request
123     send(smartSock(), nlMsg, nlMsg->nlmsg_len, 0);
124 
125     int i = 3;
126     while (i--)
127     {
128         //wait for timer to expire
129         std::this_thread::sleep_for(
130             std::chrono::milliseconds(refreshTimeout));
131         sd_event_run(eventPtr.get(), 10);
132     };
133 
134     EXPECT_EQ(true, isInterfaceAdded("igb5"));
135 }
136 
137 }// namespce network
138 }// namespace phosphor
139