Move the netlink command code to a new NetlinkCommands file.

Test: bullhead builds, netd boots
Test: netd_{unit,integration}_test pass
Bug: 34873832
Change-Id: Ia6fcde63e1092a62cad1c5238bbb9a91a9f39080
diff --git a/server/RouteController.cpp b/server/RouteController.cpp
index f61a5ef..a0fd7d5 100644
--- a/server/RouteController.cpp
+++ b/server/RouteController.cpp
@@ -29,6 +29,7 @@
 
 #include "DummyNetwork.h"
 #include "Fwmark.h"
+#include "NetlinkCommands.h"
 #include "UidRanges.h"
 
 #include "android-base/file.h"
@@ -94,8 +95,6 @@
 const uint16_t NETLINK_REQUEST_FLAGS = NLM_F_REQUEST | NLM_F_ACK;
 const uint16_t NETLINK_CREATE_REQUEST_FLAGS = NETLINK_REQUEST_FLAGS | NLM_F_CREATE | NLM_F_EXCL;
 
-const sockaddr_nl NETLINK_ADDRESS = {AF_NETLINK, 0, 0, 0};
-
 const uint8_t AF_FAMILIES[] = {AF_INET, AF_INET6};
 
 const char* const IP_VERSIONS[] = {"-4", "-6"};
@@ -199,70 +198,6 @@
     }
 }
 
-// Sends a netlink request and possibly expects an ack.
-// |iov| is an array of struct iovec that contains the netlink message payload.
-// The netlink header is generated by this function based on |action| and |flags|.
-// Returns -errno if there was an error or if the kernel reported an error.
-
-// Disable optimizations in ASan build.
-// ASan reports an out-of-bounds 32-bit(!) access in the first loop of the
-// function (over iov[]).
-#ifdef __clang__
-#if __has_feature(address_sanitizer)
-__attribute__((optnone))
-#endif
-#endif
-WARN_UNUSED_RESULT int sendNetlinkRequest(uint16_t action, uint16_t flags, iovec* iov, int iovlen) {
-    nlmsghdr nlmsg = {
-        .nlmsg_type = action,
-        .nlmsg_flags = flags,
-    };
-    iov[0].iov_base = &nlmsg;
-    iov[0].iov_len = sizeof(nlmsg);
-    for (int i = 0; i < iovlen; ++i) {
-        nlmsg.nlmsg_len += iov[i].iov_len;
-    }
-
-    int sock = socket(AF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_ROUTE);
-    if (sock == -1) {
-        return -errno;
-    }
-
-    int ret = 0;
-    struct {
-        nlmsghdr msg;
-        nlmsgerr err;
-    } response;
-
-
-    if (connect(sock, reinterpret_cast<const sockaddr*>(&NETLINK_ADDRESS),
-                sizeof(NETLINK_ADDRESS)) == -1 || writev(sock, iov, iovlen) == -1) {
-        ret = -errno;
-        ALOGE("netlink socket connect/writev failed (%s)", strerror(-ret));
-        close(sock);
-        return ret;
-    }
-
-    if (flags & NLM_F_ACK) {
-        ret = recv(sock, &response, sizeof(response), 0);
-        if (ret == sizeof(response)) {
-            ret = response.err.error;  // Netlink errors are negative errno.
-        } else if (ret == -1) {
-            ret = -errno;
-            ALOGE("netlink recv failed (%s)", strerror(-ret));
-        } else {
-            ALOGE("bad netlink response message size (%d != %zu)", ret, sizeof(response));
-            ret = -EBADMSG;
-        }
-    }
-
-    if (sock != -1) {
-        close(sock);
-    }
-
-    return ret;
-}
-
 // Returns 0 on success or negative errno on failure.
 int padInterfaceName(const char* input, char* name, size_t* length, uint16_t* padding) {
     if (!input) {