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