Add destination host exemption to VPN routing

requestRouteToHost requires the ability to punch holes in the VPN for
certain addresses, this adds support for this under mark based VPNs.

Change-Id: I9d890829048624d43c0f1efaec54563a860e850f
diff --git a/SecondaryTableController.cpp b/SecondaryTableController.cpp
index 0a4d108..b63d416 100644
--- a/SecondaryTableController.cpp
+++ b/SecondaryTableController.cpp
@@ -37,6 +37,7 @@
 #include "SecondaryTableController.h"
 
 const char* SecondaryTableController::LOCAL_MANGLE_OUTPUT = "st_mangle_OUTPUT";
+const char* SecondaryTableController::LOCAL_MANGLE_EXEMPT = "st_mangle_EXEMPT";
 const char* SecondaryTableController::LOCAL_MANGLE_IFACE_FORMAT = "st_mangle_%s_OUTPUT";
 const char* SecondaryTableController::LOCAL_NAT_POSTROUTING = "st_nat_POSTROUTING";
 const char* SecondaryTableController::LOCAL_FILTER_OUTPUT = "st_filter_OUTPUT";
@@ -60,6 +61,12 @@
             "-F",
             LOCAL_MANGLE_OUTPUT,
             NULL);
+    res |= execIptables(V4V6,
+            "-t",
+            "mangle",
+            "-F",
+            LOCAL_MANGLE_EXEMPT,
+            NULL);
     //rule for skipping anything marked with the PROTECT_MARK
     char protect_mark_str[11];
     snprintf(protect_mark_str, sizeof(protect_mark_str), "%d", PROTECT_MARK);
@@ -576,6 +583,32 @@
             NULL);
 }
 
+int SecondaryTableController::addHostExemption(const char *host) {
+    return setHostExemption(host, true);
+}
+
+int SecondaryTableController::removeHostExemption(const char *host) {
+    return setHostExemption(host, false);
+}
+
+int SecondaryTableController::setHostExemption(const char *host, bool add) {
+    IptablesTarget target = !strcmp(getVersion(host), "-4") ? V4 : V6;
+    char protect_mark_str[11];
+    snprintf(protect_mark_str, sizeof(protect_mark_str), "%d", PROTECT_MARK);
+    return execIptables(target,
+            "-t",
+            "mangle",
+            add ? "-A" : "-D",
+            LOCAL_MANGLE_EXEMPT,
+            "-d",
+            host,
+            "-j",
+            "MARK",
+            "--set-mark",
+            protect_mark_str,
+            NULL);
+}
+
 int SecondaryTableController::runCmd(int argc, const char **argv) {
     int ret = 0;