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             char tmp[] = "/tmp/NetworkManager.XXXXXX";
83             confDir = mkdtemp(tmp);
84             manager->setConfDir(confDir);
85         }
86 
87         bool isInterfaceAdded(std::string intf)
88         {
89             return manager->interfaces.find(intf) != manager->interfaces.end()?
90                    true :
91                    false;
92         }
93 
94         void createNetLinkSocket()
95         {
96             //RtnetLink socket
97             auto fd = socket(PF_NETLINK, SOCK_RAW | SOCK_NONBLOCK,
98                 NETLINK_ROUTE);
99             smartSock.set(fd);
100         }
101 };
102 
103 
104 TEST_F(TestRtNetlink, WithSingleInterface)
105 {
106     using namespace std::chrono;
107     // Adds the following ip in the getifaddrs list.
108     mock_addIP("igb5", "127.0.0.1", "255.255.255.128",
109                IFF_UP | IFF_RUNNING);
110     constexpr auto BUFSIZE = 4096;
111     std::array<char, BUFSIZE> msgBuf = {0};
112 
113     // point the header and the msg structure pointers into the buffer.
114     auto nlMsg = reinterpret_cast<nlmsghdr*>(msgBuf.data());
115     // Length of message
116     nlMsg->nlmsg_len = NLMSG_LENGTH(sizeof(rtmsg));
117     nlMsg->nlmsg_type = RTM_GETADDR;
118     nlMsg->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST;
119     nlMsg->nlmsg_seq = 0;
120     nlMsg->nlmsg_pid = getpid();
121 
122     EXPECT_EQ(false, isInterfaceAdded("igb5"));
123     // Send the request
124     send(smartSock(), nlMsg, nlMsg->nlmsg_len, 0);
125 
126     int i = 3;
127     while (i--)
128     {
129         //wait for timer to expire
130         std::this_thread::sleep_for(
131             std::chrono::milliseconds(refreshTimeout));
132         sd_event_run(eventPtr.get(), 10);
133     };
134 
135     EXPECT_EQ(true, isInterfaceAdded("igb5"));
136 }
137 
138 }// namespce network
139 }// namespace phosphor
140