Merge "Remove Broadcom hack for BT reverse Tether" into jb-mr2-dev
diff --git a/CommandListener.cpp b/CommandListener.cpp
index b2c3533..e8876b5 100644
--- a/CommandListener.cpp
+++ b/CommandListener.cpp
@@ -549,6 +549,21 @@
         cli->sendMsg(ResponseCode::TetherStatusResult, tmp, false);
         free(tmp);
         return 0;
+    } else if (argc == 3) {
+        if (!strcmp(argv[1], "interface") && !strcmp(argv[2], "list")) {
+            InterfaceCollection *ilist = sTetherCtrl->getTetheredInterfaceList();
+            InterfaceCollection::iterator it;
+            for (it = ilist->begin(); it != ilist->end(); ++it) {
+                cli->sendMsg(ResponseCode::TetherInterfaceListResult, *it, false);
+            }
+        } else if (!strcmp(argv[1], "dns") && !strcmp(argv[2], "list")) {
+            NetAddressCollection *dlist = sTetherCtrl->getDnsForwarders();
+            NetAddressCollection::iterator it;
+
+            for (it = dlist->begin(); it != dlist->end(); ++it) {
+                cli->sendMsg(ResponseCode::TetherDnsFwdTgtListResult, inet_ntoa(*it), false);
+            }
+        }
     } else {
         /*
          * These commands take a minimum of 4 arguments
@@ -582,13 +597,7 @@
                 rc = sTetherCtrl->tetherInterface(argv[3]);
             } else if (!strcmp(argv[2], "remove")) {
                 rc = sTetherCtrl->untetherInterface(argv[3]);
-            } else if (!strcmp(argv[2], "list")) {
-                InterfaceCollection *ilist = sTetherCtrl->getTetheredInterfaceList();
-                InterfaceCollection::iterator it;
-
-                for (it = ilist->begin(); it != ilist->end(); ++it) {
-                    cli->sendMsg(ResponseCode::TetherInterfaceListResult, *it, false);
-                }
+            /* else if (!strcmp(argv[2], "list")) handled above */
             } else {
                 cli->sendMsg(ResponseCode::CommandParameterError,
                              "Unknown tether interface operation", false);
@@ -597,13 +606,7 @@
         } else if (!strcmp(argv[1], "dns")) {
             if (!strcmp(argv[2], "set")) {
                 rc = sTetherCtrl->setDnsForwarders(&argv[3], argc - 3);
-            } else if (!strcmp(argv[2], "list")) {
-                NetAddressCollection *dlist = sTetherCtrl->getDnsForwarders();
-                NetAddressCollection::iterator it;
-
-                for (it = dlist->begin(); it != dlist->end(); ++it) {
-                    cli->sendMsg(ResponseCode::TetherDnsFwdTgtListResult, inet_ntoa(*it), false);
-                }
+            /* else if (!strcmp(argv[2], "list")) handled above */
             } else {
                 cli->sendMsg(ResponseCode::CommandParameterError,
                              "Unknown tether interface operation", false);
diff --git a/NatController.cpp b/NatController.cpp
index ff35d89..140cb36 100644
--- a/NatController.cpp
+++ b/NatController.cpp
@@ -45,6 +45,12 @@
 NatController::~NatController() {
 }
 
+struct CommandsAndArgs {
+    /* The array size doesn't really matter as the compiler will barf if too many initializers are specified. */
+    const char *cmd[32];
+    bool checkRes;
+};
+
 int NatController::runCmd(int argc, const char **argv) {
     int res;
 
@@ -59,100 +65,24 @@
 }
 
 int NatController::setDefaults() {
-    const char *cmd1[] = {
-            IPTABLES_PATH,
-            "-F",
-            "natctrl_FORWARD"
+    struct CommandsAndArgs defaultCommands[] = {
+        {{IPTABLES_PATH, "-F", "natctrl_FORWARD",}, 1},
+        {{IPTABLES_PATH, "-A", "natctrl_FORWARD", "-j", "DROP"}, 1},
+        {{IPTABLES_PATH, "-t", "nat", "-F", "natctrl_nat_POSTROUTING"}, 1},
+        {{IP_PATH, "rule", "flush"}, 0},
+        {{IP_PATH, "-6", "rule", "flush"}, 0},
+        {{IP_PATH, "rule", "add", "from", "all", "lookup", "default", "prio", "32767"}, 0},
+        {{IP_PATH, "rule", "add", "from", "all", "lookup", "main", "prio", "32766"}, 0},
+        {{IP_PATH, "-6", "rule", "add", "from", "all", "lookup", "default", "prio", "32767"}, 0},
+        {{IP_PATH, "-6", "rule", "add", "from", "all", "lookup", "main", "prio", "32766"}, 0},
+        {{IP_PATH, "route", "flush", "cache"}, 0},
     };
-    if (runCmd(ARRAY_SIZE(cmd1), cmd1))
-        return -1;
-
-    const char *cmd2[] = {
-            IPTABLES_PATH,
-            "-t",
-            "nat",
-            "-F",
-            "natctrl_nat_POSTROUTING"
-    };
-    if (runCmd(ARRAY_SIZE(cmd2), cmd2))
-        return -1;
-
-    const char *cmd3[] = {
-            IP_PATH,
-            "rule",
-            "flush"
-    };
-    runCmd(ARRAY_SIZE(cmd3), cmd3);
-
-    const char *cmd4[] = {
-            IP_PATH,
-            "-6",
-            "rule",
-            "flush"
-    };
-    runCmd(ARRAY_SIZE(cmd4), cmd4);
-
-    const char *cmd5[] = {
-            IP_PATH,
-            "rule",
-            "add",
-            "from",
-            "all",
-            "lookup",
-            "default",
-            "prio",
-            "32767"
-    };
-    runCmd(ARRAY_SIZE(cmd5), cmd5);
-
-    const char *cmd6[] = {
-            IP_PATH,
-            "rule",
-            "add",
-            "from",
-            "all",
-            "lookup",
-            "main",
-            "prio",
-            "32766"
-    };
-    runCmd(ARRAY_SIZE(cmd6), cmd6);
-
-    const char *cmd7[] = {
-            IP_PATH,
-            "-6",
-            "rule",
-            "add",
-            "from",
-            "all",
-            "lookup",
-            "default",
-            "prio",
-            "32767"
-    };
-    runCmd(ARRAY_SIZE(cmd7), cmd7);
-
-    const char *cmd8[] = {
-            IP_PATH,
-            "-6",
-            "rule",
-            "add",
-            "from",
-            "all",
-            "lookup",
-            "main",
-            "prio",
-            "32766"
-    };
-    runCmd(ARRAY_SIZE(cmd8), cmd8);
-
-    const char *cmd9[] = {
-            IP_PATH,
-            "route",
-            "flush",
-            "cache"
-    };
-    runCmd(ARRAY_SIZE(cmd9), cmd9);
+    for (unsigned int cmdNum = 0; cmdNum < ARRAY_SIZE(defaultCommands); cmdNum++) {
+        if (runCmd(ARRAY_SIZE(defaultCommands[cmdNum].cmd), defaultCommands[cmdNum].cmd) &&
+            defaultCommands[cmdNum].checkRes) {
+                return -1;
+        }
+    }
 
     natCount = 0;
 
@@ -164,12 +94,36 @@
     return true;
 }
 
+int NatController::routesOp(bool add, const char *intIface, const char *extIface, char **argv, int addrCount) {
+    int tableNumber = secondaryTableCtrl->findTableNumber(extIface);
+    int ret = 0;
+
+    if (tableNumber != -1) {
+        for (int i = 0; i < addrCount; i++) {
+            if (add) {
+                ret |= secondaryTableCtrl->modifyFromRule(tableNumber, ADD, argv[5+i]);
+                ret |= secondaryTableCtrl->modifyLocalRoute(tableNumber, ADD, intIface, argv[5+i]);
+            } else {
+                ret |= secondaryTableCtrl->modifyLocalRoute(tableNumber, DEL, intIface, argv[5+i]);
+                ret |= secondaryTableCtrl->modifyFromRule(tableNumber, DEL, argv[5+i]);
+            }
+        }
+        const char *cmd[] = {
+                IP_PATH,
+                "route",
+                "flush",
+                "cache"
+        };
+        runCmd(ARRAY_SIZE(cmd), cmd);
+    }
+    return ret;
+}
+
 //  0    1       2       3       4            5
 // nat enable intface extface addrcnt nated-ipaddr/prelength
 int NatController::enableNat(const int argc, char **argv) {
     int i;
     int addrCount = atoi(argv[4]);
-    int ret = 0;
     const char *intIface = argv[2];
     const char *extIface = argv[3];
     int tableNumber;
@@ -185,39 +139,42 @@
         errno = EINVAL;
         return -1;
     }
-
-    tableNumber = secondaryTableCtrl->findTableNumber(extIface);
-    if (tableNumber != -1) {
-        for(i = 0; i < addrCount; i++) {
-            ret |= secondaryTableCtrl->modifyFromRule(tableNumber, ADD, argv[5+i]);
-
-            ret |= secondaryTableCtrl->modifyLocalRoute(tableNumber, ADD, intIface, argv[5+i]);
-        }
-        const char *cmd[] = {
-                IP_PATH,
-                "route",
-                "flush",
-                "cache"
-        };
-        runCmd(ARRAY_SIZE(cmd), cmd);
+    if (routesOp(true, intIface, extIface, argv, addrCount)) {
+        ALOGE("Error setting route rules");
+        routesOp(false, intIface, extIface, argv, addrCount);
+        errno = ENODEV;
+        return -1;
     }
 
-    if (ret != 0 || setForwardRules(true, intIface, extIface) != 0) {
-        if (tableNumber != -1) {
-            for (i = 0; i < addrCount; i++) {
-                secondaryTableCtrl->modifyLocalRoute(tableNumber, DEL, intIface, argv[5+i]);
-
-                secondaryTableCtrl->modifyFromRule(tableNumber, DEL, argv[5+i]);
-            }
-            const char *cmd[] = {
-                    IP_PATH,
-                    "route",
-                    "flush",
-                    "cache"
-            };
-            runCmd(ARRAY_SIZE(cmd), cmd);
+    // add this if we are the first added nat
+    if (natCount == 0) {
+        const char *cmd[] = {
+                IPTABLES_PATH,
+                "-t",
+                "nat",
+                "-A",
+                "natctrl_nat_POSTROUTING",
+                "-o",
+                extIface,
+                "-j",
+                "MASQUERADE"
+        };
+        if (runCmd(ARRAY_SIZE(cmd), cmd)) {
+            ALOGE("Error seting postroute rule: iface=%s", extIface);
+            // unwind what's been done, but don't care about success - what more could we do?
+            routesOp(false, intIface, extIface, argv, addrCount);
+            setDefaults();
+            return -1;
         }
+    }
+
+
+    if (setForwardRules(true, intIface, extIface) != 0) {
         ALOGE("Error setting forward rules");
+        routesOp(false, intIface, extIface, argv, addrCount);
+        if (natCount == 0) {
+            setDefaults();
+        }
         errno = ENODEV;
         return -1;
     }
@@ -240,34 +197,7 @@
     };
     runCmd(ARRAY_SIZE(cmd2), cmd2);
 
-
     natCount++;
-    // add this if we are the first added nat
-    if (natCount == 1) {
-        const char *cmd[] = {
-                IPTABLES_PATH,
-                "-t",
-                "nat",
-                "-A",
-                "natctrl_nat_POSTROUTING",
-                "-o",
-                extIface,
-                "-j",
-                "MASQUERADE"
-        };
-        if (runCmd(ARRAY_SIZE(cmd), cmd)) {
-            ALOGE("Error seting postroute rule: iface=%s", extIface);
-            // unwind what's been done, but don't care about success - what more could we do?
-            for (i = 0; i < addrCount; i++) {
-                secondaryTableCtrl->modifyLocalRoute(tableNumber, DEL, intIface, argv[5+i]);
-
-                secondaryTableCtrl->modifyFromRule(tableNumber, DEL, argv[5+i]);
-            }
-            setDefaults();
-            return -1;
-        }
-    }
-
     return 0;
 }
 
@@ -367,24 +297,7 @@
     }
 
     setForwardRules(false, intIface, extIface);
-
-    tableNumber = secondaryTableCtrl->findTableNumber(extIface);
-    if (tableNumber != -1) {
-        for (i = 0; i < addrCount; i++) {
-            secondaryTableCtrl->modifyLocalRoute(tableNumber, DEL, intIface, argv[5+i]);
-
-            secondaryTableCtrl->modifyFromRule(tableNumber, DEL, argv[5+i]);
-        }
-
-        const char *cmd[] = {
-                IP_PATH,
-                "route",
-                "flush",
-                "cache"
-        };
-        runCmd(ARRAY_SIZE(cmd), cmd);
-    }
-
+    routesOp(false, intIface, extIface, argv, addrCount);
     if (--natCount <= 0) {
         // handle decrement to 0 case (do reset to defaults) and erroneous dec below 0
         setDefaults();
diff --git a/NatController.h b/NatController.h
index 4330567..ba7daaa 100644
--- a/NatController.h
+++ b/NatController.h
@@ -42,6 +42,7 @@
     int runCmd(int argc, const char **argv);
     bool checkInterface(const char *iface);
     int setForwardRules(bool set, const char *intIface, const char *extIface);
+    int routesOp(bool add, const char *intIface, const char *extIface, char **argv, int addrCount);
 };
 
 #endif