OSDN Git Service

Slightly restructure the data saver iptables rules.
authorLorenzo Colitti <lorenzo@google.com>
Fri, 18 Mar 2016 03:36:03 +0000 (12:36 +0900)
committerLorenzo Colitti <lorenzo@google.com>
Tue, 22 Mar 2016 04:14:20 +0000 (13:14 +0900)
1. Make bw_costly_shared jump to bw_happy_box after
   bw_penalty_box. This allows the framework to manipulate
   whitelists and blacklists independently.
2. Make bw_happy box always whitelist system apps. Because
   bw_penalty_box is consulted before bw_happy_box, the
   framework can always blacklist certain system apps (e.g.,
   the media server) by putting them in the blacklist.
3. Add a method to add/remove a reject at the end of
   bw_costly_shared. This will allow the framework to
   enable/disable data saver by changing only one rule.

Bug: 26685616
Bug: 27506285
Change-Id: I67bff7c3c9ff5eb3f84fb84550cdf49f153e1b68

server/BandwidthController.cpp
server/BandwidthController.h

index dcebb9f..1115cbc 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/pkt_sched.h>
 
+#include "android-base/stringprintf.h"
 #define LOG_TAG "BandwidthController"
 #include <cutils/log.h>
 #include <cutils/properties.h>
 
 /* Alphabetical */
 #define ALERT_IPT_TEMPLATE "%s %s -m quota2 ! --quota %" PRId64" --name %s"
-const char BandwidthController::ALERT_GLOBAL_NAME[] = "globalAlert";
 const char* BandwidthController::LOCAL_INPUT = "bw_INPUT";
 const char* BandwidthController::LOCAL_FORWARD = "bw_FORWARD";
 const char* BandwidthController::LOCAL_OUTPUT = "bw_OUTPUT";
 const char* BandwidthController::LOCAL_RAW_PREROUTING = "bw_raw_PREROUTING";
 const char* BandwidthController::LOCAL_MANGLE_POSTROUTING = "bw_mangle_POSTROUTING";
-const int  BandwidthController::MAX_CMD_ARGS = 32;
-const int  BandwidthController::MAX_CMD_LEN = 1024;
-const int  BandwidthController::MAX_IFACENAME_LEN = 64;
-const int  BandwidthController::MAX_IPT_OUTPUT_LINE_LEN = 256;
+
+namespace {
+
+const char ALERT_GLOBAL_NAME[] = "globalAlert";
+const int  MAX_CMD_ARGS = 32;
+const int  MAX_CMD_LEN = 1024;
+const int  MAX_IFACENAME_LEN = 64;
+const int  MAX_IPT_OUTPUT_LINE_LEN = 256;
 
 /**
  * Some comments about the rules:
@@ -82,8 +86,7 @@ const int  BandwidthController::MAX_IPT_OUTPUT_LINE_LEN = 256;
  *      iptables -I bw_costly_shared -m quota \! --quota 500000 \
  *          --jump REJECT --reject-with icmp-net-prohibited
  *      iptables -A bw_costly_shared --jump bw_penalty_box
- *      If the happy box is enabled,
- *        iptables -A bw_penalty_box --jump bw_happy_box
+ *      iptables -A bw_penalty_box --jump bw_happy_box
  *
  *    . adding a new iface to this, E.g.:
  *      iptables -I bw_INPUT -i iface1 --jump bw_costly_shared
@@ -100,17 +103,23 @@ const int  BandwidthController::MAX_IPT_OUTPUT_LINE_LEN = 256;
  *
  * * bw_penalty_box handling:
  *  - only one bw_penalty_box for all interfaces
- *   E.g  Adding an app, it has to preserve the appened bw_happy_box, so "-I":
+ *   E.g  Adding an app:
  *    iptables -I bw_penalty_box -m owner --uid-owner app_3 \
  *        --jump REJECT --reject-with icmp-port-unreachable
  *
  * * bw_happy_box handling:
- *  - The bw_happy_box goes at the end of the penalty box.
+ *  - The bw_happy_box comes after the penalty box.
  *   E.g  Adding a happy app,
  *    iptables -I bw_happy_box -m owner --uid-owner app_3 \
  *        --jump RETURN
+ *
+ * * Turning data saver on and off:
+ *  - Adds or removes a REJECT at the end of the bw_costly_shared chain
+ *    iptables -A bw_costly_shared --jump REJECT --reject-with icmp-port-unreachable
+ *    iptables -D bw_costly_shared --jump REJECT --reject-with icmp-port-unreachable
  */
-const char *BandwidthController::IPT_FLUSH_COMMANDS[] = {
+
+const char *IPT_FLUSH_COMMANDS[] = {
     /*
      * Cleanup rules.
      * Should normally include bw_costly_<iface>, but we rely on the way they are setup
@@ -128,29 +137,38 @@ const char *BandwidthController::IPT_FLUSH_COMMANDS[] = {
 };
 
 /* The cleanup commands assume flushing has been done. */
-const char *BandwidthController::IPT_CLEANUP_COMMANDS[] = {
+const char *IPT_CLEANUP_COMMANDS[] = {
     "-X bw_happy_box",
     "-X bw_penalty_box",
     "-X bw_costly_shared",
 };
 
-const char *BandwidthController::IPT_SETUP_COMMANDS[] = {
+const char *IPT_SETUP_COMMANDS[] = {
     "-N bw_happy_box",
     "-N bw_penalty_box",
     "-N bw_costly_shared",
 };
 
-const char *BandwidthController::IPT_BASIC_ACCOUNTING_COMMANDS[] = {
+const char *IPT_BASIC_ACCOUNTING_COMMANDS[] = {
     "-A bw_INPUT -m owner --socket-exists", /* This is a tracking rule. */
 
     "-A bw_OUTPUT -m owner --socket-exists", /* This is a tracking rule. */
 
-    "-A bw_costly_shared --jump bw_penalty_box",
-
     "-t raw -A bw_raw_PREROUTING -m owner --socket-exists", /* This is a tracking rule. */
     "-t mangle -A bw_mangle_POSTROUTING -m owner --socket-exists", /* This is a tracking rule. */
 };
 
+const char *COSTLY_SHARED_COMMANDS[] = {
+    "-A bw_costly_shared --jump bw_penalty_box",
+    "-A bw_costly_shared --jump bw_happy_box",
+    "-A bw_costly_shared --jump RETURN",
+};
+
+const std::string kDataSaverEnableCommand = android::base::StringPrintf(
+        "-R bw_costly_shared %zu", ARRAY_SIZE(COSTLY_SHARED_COMMANDS));
+
+}  // namespace
+
 BandwidthController::BandwidthController(void) {
 }
 
@@ -269,9 +287,17 @@ int BandwidthController::enableBandwidthControl(bool force) {
     sharedQuotaBytes = sharedAlertBytes = 0;
 
     flushCleanTables(false);
-    res = runCommands(sizeof(IPT_BASIC_ACCOUNTING_COMMANDS) / sizeof(char*),
+    res = runCommands(ARRAY_SIZE(IPT_BASIC_ACCOUNTING_COMMANDS),
             IPT_BASIC_ACCOUNTING_COMMANDS, RunCmdFailureBad);
 
+    res |= runCommands(ARRAY_SIZE(COSTLY_SHARED_COMMANDS),
+            COSTLY_SHARED_COMMANDS, RunCmdFailureBad);
+
+    char cmd[MAX_CMD_LEN];
+    snprintf(cmd, sizeof(cmd),
+            "-A bw_happy_box -m owner --uid-owner %d-%d", 0, MAX_SYSTEM_UID);
+    runIpxtablesCmd(cmd, IptJumpReturn);
+
     return res;
 
 }
@@ -282,6 +308,11 @@ int BandwidthController::disableBandwidthControl(void) {
     return 0;
 }
 
+int BandwidthController::enableDataSaver(bool enable) {
+    return runIpxtablesCmd(kDataSaverEnableCommand.c_str(),
+                           enable ? IptJumpReject : IptJumpReturn, IptFailShow);
+}
+
 int BandwidthController::runCommands(int numCommands, const char *commands[],
                                      RunCmdErrHandling cmdErrHandling) {
     int res = 0;
index c653e2f..3975303 100644 (file)
@@ -55,6 +55,7 @@ public:
 
     int enableBandwidthControl(bool force);
     int disableBandwidthControl(void);
+    int enableDataSaver(bool enable);
 
     int setInterfaceSharedQuota(const char *iface, int64_t bytes);
     int getInterfaceSharedQuota(int64_t *bytes);
@@ -196,18 +197,6 @@ protected:
 
     std::list<QuotaInfo> quotaIfaces;
 
-private:
-    static const char *IPT_FLUSH_COMMANDS[];
-    static const char *IPT_CLEANUP_COMMANDS[];
-    static const char *IPT_SETUP_COMMANDS[];
-    static const char *IPT_BASIC_ACCOUNTING_COMMANDS[];
-
-    /* Alphabetical */
-    static const char ALERT_GLOBAL_NAME[];
-    static const int  MAX_CMD_ARGS;
-    static const int  MAX_CMD_LEN;
-    static const int  MAX_IFACENAME_LEN;
-    static const int  MAX_IPT_OUTPUT_LINE_LEN;
 };
 
 #endif