Nat-related commands refine

We need this to ensure that the tethering IPCs don't need to grab the
lock in two different controllers

The idea is that always having a global_alert rule in bw_global_alert
chain.
TetherController will enable/disable the reference of bw_global_alert
chain.

[childchain order of filter FORWARD chain]
Chain FORWARD
   nm_mdmprxy_iface_pkt_fwder
   oem_fwd
   fw_FORWARD
   bw_FORWARD
   tetherctrl_FORWARD

--Simple rule comparison--
[Before]
Chain bw_FORWARD
    Alert rule
    ... other rules
Chain tetherctrl_FORWARD
    ... other rules
[After]
Chain bw_FORWARD
    No Alert rule
    ... other rules
Chain tetherctrl_FORWARD
    Jump to bw_global_alert
    ... other rules
Chain bw_global_alert
   Alert rule

The exact rule comparison is shown in the bug.

Bug:119735985
Test: built, flashed, booted
      system/netd/tests/runtests.sh passes

Change-Id: Ibf752d0c8de9170689fc74c89c0424d2642853ec
diff --git a/server/TetherController.cpp b/server/TetherController.cpp
index 49c1b7e..62dcbbf 100644
--- a/server/TetherController.cpp
+++ b/server/TetherController.cpp
@@ -507,12 +507,13 @@
         "COMMIT\n", LOCAL_FORWARD, LOCAL_FORWARD, LOCAL_NAT_POSTROUTING);
 
     std::string v6Cmd = StringPrintf(
-        "*filter\n"
-        ":%s -\n"
-        "COMMIT\n"
-        "*raw\n"
-        ":%s -\n"
-        "COMMIT\n", LOCAL_FORWARD, LOCAL_RAW_PREROUTING);
+            "*filter\n"
+            ":%s -\n"
+            "COMMIT\n"
+            "*raw\n"
+            ":%s -\n"
+            "COMMIT\n",
+            LOCAL_FORWARD, LOCAL_RAW_PREROUTING);
 
     int res = iptablesRestoreFunction(V4, v4Cmd, nullptr);
     if (res < 0) {
@@ -552,8 +553,8 @@
             "COMMIT\n"
         };
 
-        if (iptablesRestoreFunction(V4, Join(v4Cmds, '\n'), nullptr) ||
-            setupIPv6CountersChain()) {
+        if (iptablesRestoreFunction(V4, Join(v4Cmds, '\n'), nullptr) || setupIPv6CountersChain() ||
+            setTetherGlobalAlertRule()) {
             ALOGE("Error setting postroute rule: iface=%s", extIface);
             if (!isAnyForwardingPairEnabled()) {
                 // unwind what's been done, but don't care about success - what more could we do?
@@ -574,6 +575,19 @@
     return 0;
 }
 
+int TetherController::setTetherGlobalAlertRule() {
+    // Only add this if we are the first enabled nat
+    if (isAnyForwardingPairEnabled()) {
+        return 0;
+    }
+    const std::string cmds =
+            "*filter\n" +
+            StringPrintf("-I %s -j %s\n", LOCAL_FORWARD, BandwidthController::LOCAL_GLOBAL_ALERT) +
+            "COMMIT\n";
+
+    return iptablesRestoreFunction(V4V6, cmds, nullptr);
+}
+
 int TetherController::setupIPv6CountersChain() {
     // Only add this if we are the first enabled nat
     if (isAnyForwardingPairEnabled()) {
@@ -584,13 +598,11 @@
      * IPv6 tethering doesn't need the state-based conntrack rules, so
      * it unconditionally jumps to the tether counters chain all the time.
      */
-    std::vector<std::string> v6Cmds = {
-        "*filter",
-        StringPrintf("-A %s -g %s", LOCAL_FORWARD, LOCAL_TETHER_COUNTERS_CHAIN),
-        "COMMIT\n"
-    };
+    const std::string v6Cmds =
+            "*filter\n" +
+            StringPrintf("-A %s -g %s\n", LOCAL_FORWARD, LOCAL_TETHER_COUNTERS_CHAIN) + "COMMIT\n";
 
-    return iptablesRestoreFunction(V6, Join(v6Cmds, '\n'), nullptr);
+    return iptablesRestoreFunction(V6, v6Cmds, nullptr);
 }
 
 // Gets a pointer to the ForwardingDownstream for an interface pair in the map, or nullptr
@@ -738,7 +750,8 @@
 
 int TetherController::disableNat(const char* intIface, const char* extIface) {
     if (!isIfaceName(intIface) || !isIfaceName(extIface)) {
-        return -ENODEV;
+        errno = ENODEV;
+        return -errno;
     }
 
     setForwardRules(false, intIface, extIface);