Convert set*Quota to use iptablesRestore.

Bug: 28362720
Test: bullhead builds,boots
Test: netd_{unit,integration}_test pass
Test: quota rules are added and removed when quotas are enabled/disabled
Change-Id: Ib4df4f10a26c8bc206cc67671da09618fa4224ac
diff --git a/server/BandwidthControllerTest.cpp b/server/BandwidthControllerTest.cpp
index 1886ad6..4371d00 100644
--- a/server/BandwidthControllerTest.cpp
+++ b/server/BandwidthControllerTest.cpp
@@ -42,6 +42,7 @@
 using ::testing::Test;
 using ::testing::_;
 
+using android::base::Join;
 using android::base::StringPrintf;
 using android::net::TunInterface;
 using android::netdutils::status::ok;
@@ -230,7 +231,7 @@
     expectIptablesRestoreCommands(expected);
 }
 
-std::string kIPv4TetherCounters = android::base::Join(std::vector<std::string> {
+std::string kIPv4TetherCounters = Join(std::vector<std::string> {
     "Chain natctrl_tether_counters (4 references)",
     "    pkts      bytes target     prot opt in     out     source               destination",
     "      26     2373 RETURN     all  --  wlan0  rmnet0  0.0.0.0/0            0.0.0.0/0",
@@ -239,7 +240,7 @@
     "    1450  1708806 RETURN     all  --  rmnet0 bt-pan  0.0.0.0/0            0.0.0.0/0",
 }, '\n');
 
-std::string kIPv6TetherCounters = android::base::Join(std::vector<std::string> {
+std::string kIPv6TetherCounters = Join(std::vector<std::string> {
     "Chain natctrl_tether_counters (2 references)",
     "    pkts      bytes target     prot opt in     out     source               destination",
     "   10000 10000000 RETURN     all      wlan0  rmnet0  ::/0                 ::/0",
@@ -346,7 +347,7 @@
     std::vector<std::string> counterLines = android::base::Split(kIPv4TetherCounters, "\n");
     std::vector<std::string> brokenCounterLines = counterLines;
     counterLines.resize(4);
-    std::string counters = android::base::Join(counterLines, "\n") + "\n";
+    std::string counters = Join(counterLines, "\n") + "\n";
     addIptablesRestoreOutput(counters, counters);
     expected =
             "114 wlan0 rmnet0 4746 52 4004 54\n"
@@ -358,7 +359,7 @@
     // But if interfaces aren't paired, it's always an error.
     err = "";
     counterLines.resize(3);
-    counters = android::base::Join(counterLines, "\n") + "\n";
+    counters = Join(counterLines, "\n") + "\n";
     addIptablesRestoreOutput(counters, counters);
     ASSERT_EQ(-1, mBw.getTetherStats(&cli, filter, err));
     expectNoSocketClientResponse(socketPair[1]);
@@ -386,16 +387,17 @@
     const char* c_chain = chain.c_str();
     const char* c_iface = iface.c_str();
     std::vector<std::string> cmds = {
-        StringPrintf("-N %s", c_chain),
-        StringPrintf("-F %s", c_chain),
+        "*filter",
+        StringPrintf(":%s -", c_chain),
         StringPrintf("-A %s -j bw_penalty_box", c_chain),
         StringPrintf("-I bw_INPUT %d -i %s --jump %s", ruleIndex, c_iface, c_chain),
         StringPrintf("-I bw_OUTPUT %d -o %s --jump %s", ruleIndex, c_iface, c_chain),
         StringPrintf("-A bw_FORWARD -o %s --jump %s", c_iface, c_chain),
         StringPrintf("-A %s -m quota2 ! --quota %" PRIu64 " --name %s --jump REJECT", c_chain,
                      quota, c_iface),
+        "COMMIT\n",
     };
-    return cmds;
+    return {Join(cmds, "\n")};
 }
 
 const std::vector<std::string> removeInterfaceQuotaCommands(const std::string& iface) {
@@ -403,13 +405,15 @@
     const char* c_chain = chain.c_str();
     const char* c_iface = iface.c_str();
     std::vector<std::string> cmds = {
+        "*filter",
         StringPrintf("-D bw_INPUT -i %s --jump %s", c_iface, c_chain),
         StringPrintf("-D bw_OUTPUT -o %s --jump %s", c_iface, c_chain),
         StringPrintf("-D bw_FORWARD -o %s --jump %s", c_iface, c_chain),
         StringPrintf("-F %s", c_chain),
         StringPrintf("-X %s", c_chain),
+        "COMMIT\n",
     };
-    return cmds;
+    return {Join(cmds, "\n")};
 }
 
 TEST_F(BandwidthControllerTest, TestSetInterfaceQuota) {
@@ -418,81 +422,90 @@
     std::vector<std::string> expected = makeInterfaceQuotaCommands(iface, 1, kOldQuota);
 
     EXPECT_EQ(0, mBw.setInterfaceQuota(iface, kOldQuota));
-    expectIptablesCommands(expected);
+    expectIptablesRestoreCommands(expected);
 
     constexpr uint64_t kNewQuota = kOldQuota + 1;
     expected = {};
     expectUpdateQuota(kNewQuota);
     EXPECT_EQ(0, mBw.setInterfaceQuota(iface, kNewQuota));
-    expectIptablesCommands(expected);
+    expectIptablesRestoreCommands(expected);
 
     expected = removeInterfaceQuotaCommands(iface);
     EXPECT_EQ(0, mBw.removeInterfaceQuota(iface));
-    expectIptablesCommands(expected);
+    expectIptablesRestoreCommands(expected);
 }
 
 const std::vector<std::string> makeInterfaceSharedQuotaCommands(const std::string& iface,
-                                                                int ruleIndex, int64_t quota) {
+                                                                int ruleIndex, int64_t quota,
+                                                                bool insertQuota) {
     const std::string chain = "bw_costly_shared";
     const char* c_chain = chain.c_str();
     const char* c_iface = iface.c_str();
     std::vector<std::string> cmds = {
+        "*filter",
         StringPrintf("-I bw_INPUT %d -i %s --jump %s", ruleIndex, c_iface, c_chain),
         StringPrintf("-I bw_OUTPUT %d -o %s --jump %s", ruleIndex, c_iface, c_chain),
         StringPrintf("-A bw_FORWARD -o %s --jump %s", c_iface, c_chain),
-        StringPrintf("-I %s -m quota2 ! --quota %" PRIu64 " --name shared --jump REJECT", c_chain,
-                     quota),
     };
-    return cmds;
+    if (insertQuota) {
+        cmds.push_back(StringPrintf(
+            "-I %s -m quota2 ! --quota %" PRIu64 " --name shared --jump REJECT", c_chain, quota));
+    }
+    cmds.push_back("COMMIT\n");
+    return {Join(cmds, "\n")};
 }
 
 const std::vector<std::string> removeInterfaceSharedQuotaCommands(const std::string& iface,
-                                                                  int64_t quota) {
+                                                                  int64_t quota, bool deleteQuota) {
     const std::string chain = "bw_costly_shared";
     const char* c_chain = chain.c_str();
     const char* c_iface = iface.c_str();
     std::vector<std::string> cmds = {
+        "*filter",
         StringPrintf("-D bw_INPUT -i %s --jump %s", c_iface, c_chain),
         StringPrintf("-D bw_OUTPUT -o %s --jump %s", c_iface, c_chain),
         StringPrintf("-D bw_FORWARD -o %s --jump %s", c_iface, c_chain),
-        StringPrintf("-D %s -m quota2 ! --quota %" PRIu64
-                     " --name shared --jump REJECT", c_chain, quota),
     };
-    return cmds;
+    if (deleteQuota) {
+        cmds.push_back(StringPrintf(
+            "-D %s -m quota2 ! --quota %" PRIu64 " --name shared --jump REJECT", c_chain, quota));
+    }
+    cmds.push_back("COMMIT\n");
+    return {Join(cmds, "\n")};
 }
 
 TEST_F(BandwidthControllerTest, TestSetInterfaceSharedQuotaDuplicate) {
     constexpr uint64_t kQuota = 123456;
     const std::string iface = mTun.name();
-    std::vector<std::string> expected = makeInterfaceSharedQuotaCommands(iface, 1, 123456);
+    std::vector<std::string> expected = makeInterfaceSharedQuotaCommands(iface, 1, 123456, true);
     EXPECT_EQ(0, mBw.setInterfaceSharedQuota(iface, kQuota));
-    expectIptablesCommands(expected);
+    expectIptablesRestoreCommands(expected);
 
     expected = {};
     EXPECT_EQ(0, mBw.setInterfaceSharedQuota(iface, kQuota));
-    expectIptablesCommands(expected);
+    expectIptablesRestoreCommands(expected);
 
-    expected = removeInterfaceSharedQuotaCommands(iface, kQuota);
+    expected = removeInterfaceSharedQuotaCommands(iface, kQuota, true);
     EXPECT_EQ(0, mBw.removeInterfaceSharedQuota(iface));
-    expectIptablesCommands(expected);
+    expectIptablesRestoreCommands(expected);
 }
 
 TEST_F(BandwidthControllerTest, TestSetInterfaceSharedQuotaUpdate) {
     constexpr uint64_t kOldQuota = 123456;
     const std::string iface = mTun.name();
-    std::vector<std::string> expected = makeInterfaceSharedQuotaCommands(iface, 1, kOldQuota);
+    std::vector<std::string> expected = makeInterfaceSharedQuotaCommands(iface, 1, kOldQuota, true);
     EXPECT_EQ(0, mBw.setInterfaceSharedQuota(iface, kOldQuota));
-    expectIptablesCommands(expected);
+    expectIptablesRestoreCommands(expected);
 
     constexpr uint64_t kNewQuota = kOldQuota + 1;
     expected = {};
     expectUpdateQuota(kNewQuota);
     EXPECT_EQ(0, mBw.setInterfaceSharedQuota(iface, kNewQuota));
-    expectIptablesCommands(expected);
+    expectIptablesRestoreCommands(expected);
 
-    expected = removeInterfaceSharedQuotaCommands(iface, kNewQuota);
+    expected = removeInterfaceSharedQuotaCommands(iface, kNewQuota, true);
     EXPECT_EQ(0, mBw.removeInterfaceSharedQuota(iface));
-    expectIptablesCommands(expected);
+    expectIptablesRestoreCommands(expected);
 }
 
 TEST_F(BandwidthControllerTest, TestSetInterfaceSharedQuotaTwoInterfaces) {
@@ -503,27 +516,21 @@
     };
 
     for (const auto& iface : ifaces) {
+        // Quota rule is only added when the total number of
+        // interfaces transitions from 0 -> 1.
         bool first = (iface == ifaces[0]);
-        auto expected = makeInterfaceSharedQuotaCommands(iface, 1, kQuota);
-        if (!first) {
-            // Quota rule is only added when the total number of
-            // interfaces transitions from 0 -> 1.
-            expected.pop_back();
-        }
+        auto expected = makeInterfaceSharedQuotaCommands(iface, 1, kQuota, first);
         EXPECT_EQ(0, mBw.setInterfaceSharedQuota(iface, kQuota));
-        expectIptablesCommands(expected);
+        expectIptablesRestoreCommands(expected);
     }
 
     for (const auto& iface : ifaces) {
+        // Quota rule is only removed when the total number of
+        // interfaces transitions from 1 -> 0.
         bool last = (iface == ifaces[1]);
-        auto expected = removeInterfaceSharedQuotaCommands(iface, kQuota);
-        if (!last) {
-            // Quota rule is only removed when the total number of
-            // interfaces transitions from 1 -> 0.
-            expected.pop_back();
-        }
+        auto expected = removeInterfaceSharedQuotaCommands(iface, kQuota, last);
         EXPECT_EQ(0, mBw.removeInterfaceSharedQuota(iface));
-        expectIptablesCommands(expected);
+        expectIptablesRestoreCommands(expected);
     }
 }