Create netlink socket outside from rtnetlink server

As socket lifetime goes out of scope before starting the
sd event loop,so now create the socket outside and pass
it to rtnetlink server.

Resolves openbmc/openbmc#2562
Resolves openbmc/openbmc#2575
Resolves openbmc/openbmc#2632

Change-Id: If80a9cc3556c201a8864836e738d23fcef80b9e7
Signed-off-by: Ratan Gupta <ratagupt@in.ibm.com>
diff --git a/network_manager_main.cpp b/network_manager_main.cpp
index b08d5ac..3828c9b 100644
--- a/network_manager_main.cpp
+++ b/network_manager_main.cpp
@@ -5,11 +5,14 @@
 #include "watch.hpp"
 #include "dns_updater.hpp"
 
-#include <memory>
+#include <linux/netlink.h>
 
+#include <memory>
+#include <phosphor-logging/elog-errors.hpp>
 #include <phosphor-logging/log.hpp>
 #include <sdbusplus/bus.hpp>
 #include <sdbusplus/server/manager.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
 
 namespace phosphor
 {
@@ -53,6 +56,25 @@
         std::make_unique<phosphor::network::Timer>(restartFunc);
 }
 
+void createNetLinkSocket(phosphor::Descriptor& smartSock)
+{
+    using namespace phosphor::logging;
+    using InternalFailure = sdbusplus::xyz::openbmc_project::Common::
+                                    Error::InternalFailure;
+    //RtnetLink socket
+    auto fd = socket(PF_NETLINK, SOCK_RAW | SOCK_NONBLOCK, NETLINK_ROUTE);
+    if (fd < 0)
+    {
+        auto r = -errno;
+        log<level::ERR>("Unable to create the net link socket",
+                        entry("ERRNO=%d", r));
+        elog<InternalFailure>();
+    }
+    smartSock.set(fd);
+}
+
+
+
 int main(int argc, char *argv[])
 {
     using namespace phosphor::logging;
@@ -100,8 +122,12 @@
         phosphor::network::restartNetwork();
     }
 
+    //RtnetLink socket
+    phosphor::Descriptor smartSock;
+    createNetLinkSocket(smartSock);
+
     // RTNETLINK event handler
-    phosphor::network::rtnetlink::Server svr(eventPtr);
+    phosphor::network::rtnetlink::Server svr(eventPtr, smartSock);
 
     // DNS entry handler
     phosphor::network::inotify::Watch watch(eventPtr, DNS_ENTRY_FILE,
@@ -114,7 +140,6 @@
     // waiting on change events
     phosphor::network::dns::updater::processDNSEntries(DNS_ENTRY_FILE);
 
-    // Run the server
     sd_event_loop(eventPtr.get());
 }
 
diff --git a/rtnetlink_server.cpp b/rtnetlink_server.cpp
index 2e1c5bb..955706c 100644
--- a/rtnetlink_server.cpp
+++ b/rtnetlink_server.cpp
@@ -65,20 +65,21 @@
     return 0;
 }
 
-Server::Server(EventPtr& eventPtr)
+Server::Server(EventPtr& eventPtr, const phosphor::Descriptor& smartSock)
 {
     using namespace phosphor::logging;
     using InternalFailure = sdbusplus::xyz::openbmc_project::Common::
                                     Error::InternalFailure;
     struct sockaddr_nl addr {};
-
-    int fd = -1;
-    phosphor::Descriptor smartSock(fd);
-
     int r {};
 
     sigset_t ss {};
-
+    // check that the given socket is valid or not.
+    if(smartSock() < 0)
+    {
+        r = -EBADF;
+        goto finish;
+    }
 
     if (sigemptyset(&ss) < 0 || sigaddset(&ss, SIGTERM) < 0 ||
         sigaddset(&ss, SIGINT) < 0)
@@ -108,16 +109,6 @@
         goto finish;
     }
 
-    fd = socket(PF_NETLINK, SOCK_RAW | SOCK_NONBLOCK, NETLINK_ROUTE);
-    if (fd < 0)
-    {
-        r = -errno;
-        goto finish;
-    }
-
-    smartSock.set(fd);
-    fd = -1;
-
     memset(&addr, 0, sizeof(addr));
     addr.nl_family = AF_NETLINK;
     addr.nl_groups = RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR;
diff --git a/rtnetlink_server.hpp b/rtnetlink_server.hpp
index a00e6b7..0991ae0 100644
--- a/rtnetlink_server.hpp
+++ b/rtnetlink_server.hpp
@@ -30,8 +30,9 @@
          *  @details Sets up the server to handle incoming RTNETLINK events
          *
          *  @param[in] eventPtr - Unique ptr reference to sd_event.
+         *  @param[in] socket - netlink socket.
          */
-        Server(EventPtr& eventPtr);
+        Server(EventPtr& eventPtr, const phosphor::Descriptor& socket);
 
         Server() = delete;
         ~Server() = default;