NDC migration to binder ver.

Make ndc communicating with netd via binder

Bug: 65862741
Test: built, flashed, booted
      system/netd/tests/runtests.sh pass
      manual test ndc commands
Change-Id: I9edfda61d8c3a4d7b404a428e7dbb4d08eff62a9
diff --git a/tests/binder_test.cpp b/tests/binder_test.cpp
index 47ac2f4..da55b71 100644
--- a/tests/binder_test.cpp
+++ b/tests/binder_test.cpp
@@ -2929,4 +2929,107 @@
     const uint32_t kExpectedEvents = InterfaceAddressUpdated | InterfaceAdded | InterfaceRemoved |
                                      InterfaceLinkStatusChanged | RouteChanged;
     EXPECT_EQ(kExpectedEvents, testUnsolService->getReceived());
+
+    // Re-init sTun to clear predefined name
+    sTun.destroy();
+    sTun.init();
+}
+
+TEST_F(BinderTest, NDC) {
+    struct Command {
+        const std::string cmdString;
+        const std::string expectedResult;
+    };
+
+    // clang-format off
+    // Do not change the commands order
+    const Command networkCmds[] = {
+            {StringPrintf("ndc network create %d", TEST_NETID1),
+             "200 0 success"},
+            {StringPrintf("ndc network interface add %d %s", TEST_NETID1, sTun.name().c_str()),
+             "200 0 success"},
+            {StringPrintf("ndc network interface remove %d %s", TEST_NETID1, sTun.name().c_str()),
+             "200 0 success"},
+            {StringPrintf("ndc network interface add %d %s", TEST_NETID2, sTun.name().c_str()),
+             "400 0 addInterfaceToNetwork() failed (Machine is not on the network)"},
+            {StringPrintf("ndc network destroy %d", TEST_NETID1),
+             "200 0 success"},
+    };
+
+    const std::vector<Command> ipfwdCmds = {
+            {"ndc ipfwd enable " + sTun.name(),
+             "200 0 ipfwd operation succeeded"},
+            {"ndc ipfwd disable " + sTun.name(),
+             "200 0 ipfwd operation succeeded"},
+            {"ndc ipfwd add lo2 lo3",
+             "400 0 ipfwd operation failed (No such process)"},
+            {"ndc ipfwd add " + sTun.name() + " " + sTun2.name(),
+             "200 0 ipfwd operation succeeded"},
+            {"ndc ipfwd remove " + sTun.name() + " " + sTun2.name(),
+             "200 0 ipfwd operation succeeded"},
+    };
+
+    static const struct {
+        const char* ipVersion;
+        const char* testDest;
+        const char* testNextHop;
+        const bool expectSuccess;
+        const std::string expectedResult;
+    } kTestData[] = {
+            {IP_RULE_V4, "0.0.0.0/0",          "",            true,
+             "200 0 success"},
+            {IP_RULE_V4, "10.251.0.0/16",      "",            true,
+             "200 0 success"},
+            {IP_RULE_V4, "10.251.0.0/16",      "fe80::/64",   false,
+             "400 0 addRoute() failed (Invalid argument)",},
+            {IP_RULE_V6, "::/0",               "",            true,
+             "200 0 success"},
+            {IP_RULE_V6, "2001:db8:cafe::/64", "",            true,
+             "200 0 success"},
+            {IP_RULE_V6, "fe80::/64",          "0.0.0.0",     false,
+             "400 0 addRoute() failed (Invalid argument)"},
+    };
+    // clang-format on
+
+    for (const auto& cmd : networkCmds) {
+        const std::vector<std::string> result = runCommand(cmd.cmdString);
+        SCOPED_TRACE(cmd.cmdString);
+        EXPECT_EQ(result.size(), 1U);
+        EXPECT_EQ(cmd.expectedResult, Trim(result[0]));
+    }
+
+    for (const auto& cmd : ipfwdCmds) {
+        const std::vector<std::string> result = runCommand(cmd.cmdString);
+        SCOPED_TRACE(cmd.cmdString);
+        EXPECT_EQ(result.size(), 1U);
+        EXPECT_EQ(cmd.expectedResult, Trim(result[0]));
+    }
+
+    // Add test physical network
+    EXPECT_TRUE(mNetd->networkCreatePhysical(TEST_NETID1, INetd::PERMISSION_NONE).isOk());
+    EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());
+
+    for (const auto& td : kTestData) {
+        const std::string routeAddCmd =
+                StringPrintf("ndc network route add %d %s %s %s", TEST_NETID1, sTun.name().c_str(),
+                             td.testDest, td.testNextHop);
+        const std::string routeRemoveCmd =
+                StringPrintf("ndc network route remove %d %s %s %s", TEST_NETID1,
+                             sTun.name().c_str(), td.testDest, td.testNextHop);
+        std::vector<std::string> result = runCommand(routeAddCmd);
+        SCOPED_TRACE(routeAddCmd);
+        EXPECT_EQ(result.size(), 1U);
+        EXPECT_EQ(td.expectedResult, Trim(result[0]));
+        if (td.expectSuccess) {
+            expectNetworkRouteExists(td.ipVersion, sTun.name(), td.testDest, td.testNextHop,
+                                     sTun.name().c_str());
+            result = runCommand(routeRemoveCmd);
+            EXPECT_EQ(result.size(), 1U);
+            EXPECT_EQ(td.expectedResult, Trim(result[0]));
+            expectNetworkRouteDoesNotExist(td.ipVersion, sTun.name(), td.testDest, td.testNextHop,
+                                           sTun.name().c_str());
+        }
+    }
+    // Remove test physical network
+    EXPECT_TRUE(mNetd->networkDestroy(TEST_NETID1).isOk());
 }