return -1;
runCmd(IP_PATH, "rule flush");
+ runCmd(IP_PATH, "-6 rule flush");
runCmd(IP_PATH, "rule add from all lookup default prio 32767");
runCmd(IP_PATH, "rule add from all lookup main prio 32766");
+ runCmd(IP_PATH, "-6 rule add from all lookup default prio 32767");
+ runCmd(IP_PATH, "-6 rule add from all lookup main prio 32766");
+ runCmd(IP_PATH, "route flush cache");
natCount = 0;
return 0;
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) {
tableNumber = secondaryTableCtrl->findTableNumber(extIface);
if (tableNumber != -1) {
for(i = 0; i < addrCount && ret == 0; i++) {
- snprintf(cmd, sizeof(cmd), "rule add from %s table %d", argv[5+i],
- tableNumber + BASE_TABLE_NUMBER);
+ 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) LOGE("IP rule %s got %d", cmd, ret);
ret |= runCmd(IP_PATH, cmd);
if (ret) LOGE("IP route %s got %d", cmd, ret);
}
+ runCmd(IP_PATH, "route flush cache");
}
if (ret != 0 || setForwardRules(true, intIface, extIface) != 0) {
tableNumber + BASE_TABLE_NUMBER);
runCmd(IP_PATH, cmd);
- snprintf(cmd, sizeof(cmd), "rule del from %s table %d", argv[5+i],
- tableNumber + BASE_TABLE_NUMBER);
+ 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);
}
+ runCmd(IP_PATH, "route flush cache");
}
LOGE("Error setting forward rules");
errno = ENODEV;
// 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);
}
+
+ runCmd(IP_PATH, "route flush cache");
}
if (--natCount <= 0) {
#include "SecondaryTableController.h"
static char IP_PATH[] = "/system/bin/ip";
+static char ADD[] = "add";
+static char DEL[] = "del";
SecondaryTableController::SecondaryTableController() {
int i;
int SecondaryTableController::addRoute(SocketClient *cli, char *iface, char *dest, int prefix,
char *gateway) {
- char *cmd;
-
int tableIndex = findTableNumber(iface);
if (tableIndex == -1) {
tableIndex = findTableNumber(""); // look for an empty slot
strncpy(mInterfaceTable[tableIndex], iface, MAX_IFACE_LENGTH);
}
- asprintf(&cmd, "%s route add %s/%d via %s table %d",
- IP_PATH, dest, prefix, gateway, tableIndex+BASE_TABLE_NUMBER);
+ return modifyRoute(cli, ADD, iface, dest, prefix, gateway, tableIndex);
+}
+
+int SecondaryTableController::modifyRoute(SocketClient *cli, char *action, char *iface, char *dest,
+ int prefix, char *gateway, int tableIndex) {
+ char *cmd;
+
+ if (strcmp("::", gateway) == 0) {
+ // IP tool doesn't like "::" - the equiv of 0.0.0.0 that it accepts for ipv4
+ asprintf(&cmd, "%s route %s %s/%d dev %s table %d",
+ IP_PATH, action, dest, prefix, iface, tableIndex+BASE_TABLE_NUMBER);
+ } else {
+ asprintf(&cmd, "%s route %s %s/%d via %s dev %s table %d",
+ IP_PATH, action, dest, prefix, gateway, iface, tableIndex+BASE_TABLE_NUMBER);
+ }
+
if (runAndFree(cli, cmd)) {
- LOGE("ip route add failed: %s", cmd);
+ LOGE("ip route %s failed: %s route %s %s/%d via %s dev %s table %d", action,
+ IP_PATH, action, dest, prefix, gateway, iface, tableIndex+BASE_TABLE_NUMBER);
errno = ENODEV;
- cli->sendMsg(ResponseCode::OperationFailed, "ip route add failed", true);
+ cli->sendMsg(ResponseCode::OperationFailed, "ip route modification failed", true);
return -1;
}
- mInterfaceRuleCount[tableIndex]++;
- cli->sendMsg(ResponseCode::CommandOkay, "Route added", false);
+
+ if (strcmp(action, ADD) == 0) {
+ mInterfaceRuleCount[tableIndex]++;
+ } else {
+ if (--mInterfaceRuleCount[tableIndex] < 1) {
+ mInterfaceRuleCount[tableIndex] = 0;
+ mInterfaceTable[tableIndex][0] = 0;
+ }
+ }
+ cli->sendMsg(ResponseCode::CommandOkay, "Route modified", false);
return 0;
}
int SecondaryTableController::removeRoute(SocketClient *cli, char *iface, char *dest, int prefix,
char *gateway) {
- char *cmd;
int tableIndex = findTableNumber(iface);
if (tableIndex == -1) {
LOGE("Interface not found");
return -1;
}
- asprintf(&cmd, "%s route del %s/%d via %s table %d",
- IP_PATH, dest, prefix, gateway, tableIndex+BASE_TABLE_NUMBER);
- if (runAndFree(cli, cmd)) {
- LOGE("ip route del failed");
- errno = ENODEV;
- cli->sendMsg(ResponseCode::OperationFailed, "ip route del failed", true);
- return -1;
- }
- if (--mInterfaceRuleCount[tableIndex]<1) {
- mInterfaceTable[tableIndex][0]=0;
- }
- cli->sendMsg(ResponseCode::CommandOkay, "Route removed", false);
- return 0;
+ return modifyRoute(cli, DEL, iface, dest, prefix, gateway, tableIndex);
}
int SecondaryTableController::runAndFree(SocketClient *cli, char *cmd) {