OSDN Git Service

Merge "Fix idletimer iptable rules."
[android-x86/system-netd.git] / NatController.cpp
index d609a39..e44a29b 100644 (file)
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+// #define LOG_NDEBUG 0
+
 #include <stdlib.h>
 #include <errno.h>
 #include <sys/socket.h>
 
 #include "NatController.h"
 #include "SecondaryTableController.h"
+#include "NetdConstants.h"
 
 extern "C" int system_nosh(const char *command);
 
-static char IPTABLES_PATH[] = "/system/bin/iptables";
-static char IP_PATH[] = "/system/bin/ip";
+const char* NatController::LOCAL_FORWARD = "natctrl_FORWARD";
+const char* NatController::LOCAL_NAT_POSTROUTING = "natctrl_nat_POSTROUTING";
 
 NatController::NatController(SecondaryTableController *ctrl) {
     secondaryTableCtrl = ctrl;
-    setDefaults();
 }
 
 NatController::~NatController() {
@@ -56,21 +58,20 @@ int NatController::runCmd(const char *path, const char *cmd) {
 
     asprintf(&buffer, "%s %s", path, cmd);
     res = system_nosh(buffer);
+    ALOGV("runCmd() buffer='%s' res=%d", buffer, res);
     free(buffer);
     return res;
 }
 
-int NatController::setDefaults() {
+int NatController::setupIptablesHooks() {
+    setDefaults();
+    return 0;
+}
 
-    if (runCmd(IPTABLES_PATH, "-P INPUT ACCEPT"))
-        return -1;
-    if (runCmd(IPTABLES_PATH, "-P OUTPUT ACCEPT"))
-        return -1;
-    if (runCmd(IPTABLES_PATH, "-P FORWARD DROP"))
-        return -1;
-    if (runCmd(IPTABLES_PATH, "-F FORWARD"))
+int NatController::setDefaults() {
+    if (runCmd(IPTABLES_PATH, "-F natctrl_FORWARD"))
         return -1;
-    if (runCmd(IPTABLES_PATH, "-t nat -F"))
+    if (runCmd(IPTABLES_PATH, "-t nat -F natctrl_nat_POSTROUTING"))
         return -1;
 
     runCmd(IP_PATH, "rule flush");
@@ -82,22 +83,15 @@ int NatController::setDefaults() {
     runCmd(IP_PATH, "route flush cache");
 
     natCount = 0;
+
     return 0;
 }
 
 bool NatController::checkInterface(const char *iface) {
-    if (strlen(iface) > MAX_IFACE_LENGTH) return false;
+    if (strlen(iface) > IFNAMSIZ) return false;
     return true;
 }
 
-const char *NatController::getVersion(const char *addr) {
-    if (strchr(addr, ':') != NULL) {
-        return "-6";
-    } else {
-        return "-4";
-    }
-}
-
 //  0    1       2       3       4            5
 // nat enable intface extface addrcnt nated-ipaddr/prelength
 int NatController::enableNat(const int argc, char **argv) {
@@ -123,16 +117,10 @@ int NatController::enableNat(const int argc, char **argv) {
 
     tableNumber = secondaryTableCtrl->findTableNumber(extIface);
     if (tableNumber != -1) {
-        for(i = 0; i < addrCount && ret == 0; i++) {
-            snprintf(cmd, sizeof(cmd), "%s rule add from %s table %d", getVersion(argv[5+i]),
-                    argv[5+i], tableNumber + BASE_TABLE_NUMBER);
-            ret |= runCmd(IP_PATH, cmd);
-            if (ret) ALOGE("IP rule %s got %d", cmd, ret);
-
-            snprintf(cmd, sizeof(cmd), "route add %s dev %s table %d", argv[5+i], intIface,
-                    tableNumber + BASE_TABLE_NUMBER);
-            ret |= runCmd(IP_PATH, cmd);
-            if (ret) ALOGE("IP route %s got %d", cmd, ret);
+        for(i = 0; i < addrCount; i++) {
+            ret |= secondaryTableCtrl->modifyFromRule(tableNumber, ADD, argv[5+i]);
+
+            ret |= secondaryTableCtrl->modifyLocalRoute(tableNumber, ADD, intIface, argv[5+i]);
         }
         runCmd(IP_PATH, "route flush cache");
     }
@@ -140,13 +128,9 @@ int NatController::enableNat(const int argc, char **argv) {
     if (ret != 0 || setForwardRules(true, intIface, extIface) != 0) {
         if (tableNumber != -1) {
             for (i = 0; i < addrCount; i++) {
-                snprintf(cmd, sizeof(cmd), "route del %s dev %s table %d", argv[5+i], intIface,
-                        tableNumber + BASE_TABLE_NUMBER);
-                runCmd(IP_PATH, cmd);
+                secondaryTableCtrl->modifyLocalRoute(tableNumber, DEL, intIface, argv[5+i]);
 
-                snprintf(cmd, sizeof(cmd), "%s rule del from %s table %d", getVersion(argv[5+i]),
-                        argv[5+i], tableNumber + BASE_TABLE_NUMBER);
-                runCmd(IP_PATH, cmd);
+                secondaryTableCtrl->modifyFromRule(tableNumber, DEL, argv[5+i]);
             }
             runCmd(IP_PATH, "route flush cache");
         }
@@ -155,17 +139,24 @@ int NatController::enableNat(const int argc, char **argv) {
         return -1;
     }
 
+    /* Always make sure the drop rule is at the end */
+    snprintf(cmd, sizeof(cmd), "-D natctrl_FORWARD -j DROP");
+    runCmd(IPTABLES_PATH, cmd);
+    snprintf(cmd, sizeof(cmd), "-A natctrl_FORWARD -j DROP");
+    runCmd(IPTABLES_PATH, cmd);
+
+
     natCount++;
     // add this if we are the first added nat
     if (natCount == 1) {
-        snprintf(cmd, sizeof(cmd), "-t nat -A POSTROUTING -o %s -j MASQUERADE", extIface);
+        snprintf(cmd, sizeof(cmd), "-t nat -A natctrl_nat_POSTROUTING -o %s -j MASQUERADE", extIface);
         if (runCmd(IPTABLES_PATH, cmd)) {
             ALOGE("Error seting postroute rule: %s", cmd);
             // unwind what's been done, but don't care about success - what more could we do?
             for (i = 0; i < addrCount; i++) {
-                snprintf(cmd, sizeof(cmd), "route del %s dev %s table %d", argv[5+i], intIface,
-                        tableNumber + BASE_TABLE_NUMBER);
-                runCmd(IP_PATH, cmd);
+                secondaryTableCtrl->modifyLocalRoute(tableNumber, DEL, intIface, argv[5+i]);
+
+                secondaryTableCtrl->modifyFromRule(tableNumber, DEL, argv[5+i]);
             }
             setDefaults();
             return -1;
@@ -179,7 +170,7 @@ int NatController::setForwardRules(bool add, const char *intIface, const char *
     char cmd[255];
 
     snprintf(cmd, sizeof(cmd),
-             "-%s FORWARD -i %s -o %s -m state --state ESTABLISHED,RELATED -j ACCEPT",
+             "-%s natctrl_FORWARD -i %s -o %s -m state --state ESTABLISHED,RELATED -j RETURN",
              (add ? "A" : "D"),
              extIface, intIface);
     if (runCmd(IPTABLES_PATH, cmd) && add) {
@@ -187,36 +178,37 @@ int NatController::setForwardRules(bool add, const char *intIface, const char *
     }
 
     snprintf(cmd, sizeof(cmd),
-            "-%s FORWARD -i %s -o %s -m state --state INVALID -j DROP",
+            "-%s natctrl_FORWARD -i %s -o %s -m state --state INVALID -j DROP",
             (add ? "A" : "D"),
             intIface, extIface);
     if (runCmd(IPTABLES_PATH, cmd) && add) {
         // bail on error, but only if adding
         snprintf(cmd, sizeof(cmd),
-                "-%s FORWARD -i %s -o %s -m state --state ESTABLISHED,RELATED -j ACCEPT",
+                "-%s natctrl_FORWARD -i %s -o %s -m state --state ESTABLISHED,RELATED -j RETURN",
                 (!add ? "A" : "D"),
                 extIface, intIface);
         runCmd(IPTABLES_PATH, cmd);
         return -1;
     }
 
-    snprintf(cmd, sizeof(cmd), "-%s FORWARD -i %s -o %s -j ACCEPT", (add ? "A" : "D"),
+    snprintf(cmd, sizeof(cmd), "-%s natctrl_FORWARD -i %s -o %s -j RETURN", (add ? "A" : "D"),
             intIface, extIface);
     if (runCmd(IPTABLES_PATH, cmd) && add) {
         // unwind what's been done, but don't care about success - what more could we do?
         snprintf(cmd, sizeof(cmd),
-                "-%s FORWARD -i %s -o %s -m state --state INVALID -j DROP",
+                "-%s natctrl_FORWARD -i %s -o %s -m state --state INVALID -j DROP",
                 (!add ? "A" : "D"),
                 intIface, extIface);
         runCmd(IPTABLES_PATH, cmd);
 
         snprintf(cmd, sizeof(cmd),
-                 "-%s FORWARD -i %s -o %s -m state --state ESTABLISHED,RELATED -j ACCEPT",
+                 "-%s natctrl_FORWARD -i %s -o %s -m state --state ESTABLISHED,RELATED -j RETURN",
                  (!add ? "A" : "D"),
                  extIface, intIface);
         runCmd(IPTABLES_PATH, cmd);
         return -1;
     }
+
     return 0;
 }
 
@@ -248,28 +240,17 @@ int NatController::disableNat(const int argc, char **argv) {
     tableNumber = secondaryTableCtrl->findTableNumber(extIface);
     if (tableNumber != -1) {
         for (i = 0; i < addrCount; i++) {
-            snprintf(cmd, sizeof(cmd), "route del %s dev %s table %d", argv[5+i], intIface,
-                    tableNumber + BASE_TABLE_NUMBER);
-            // if the interface has gone down these will be gone already and give errors
-            // ignore them.
-            runCmd(IP_PATH, cmd);
-
-            snprintf(cmd, sizeof(cmd), "%s rule del from %s table %d", getVersion(argv[5+i]),
-                    argv[5+i], tableNumber + BASE_TABLE_NUMBER);
-            runCmd(IP_PATH, cmd);
+            secondaryTableCtrl->modifyLocalRoute(tableNumber, DEL, intIface, argv[5+i]);
+
+            secondaryTableCtrl->modifyFromRule(tableNumber, DEL, argv[5+i]);
         }
 
         runCmd(IP_PATH, "route flush cache");
     }
 
     if (--natCount <= 0) {
-        char bootmode[PROPERTY_VALUE_MAX] = {0};
-        property_get("ro.bootmode", bootmode, "unknown");
-        if (0 != strcmp("bp-tools", bootmode)) {
-            // handle decrement to 0 case (do reset to defaults) and erroneous dec below 0
-            setDefaults();
-        }
-        natCount = 0;
+        // handle decrement to 0 case (do reset to defaults) and erroneous dec below 0
+        setDefaults();
     }
     return 0;
 }