netd: bandwidthcontroler: add support for alerts via iptables' quota2 log messages

* Fix quota2 updating. The old insert-new/delete-old scheme doesn't work as the kernel
 keeps the old counter assigned to the new rule.

* Add support for setting dummy quotas used only for alerts.

This needs:
 - new kernel with quota2 changes that support logging via NETLINK's
   NETLINK_NFLOG family.
 - NetlinkManager support for receiving the events.
 - java land handler for these new events.

* new commands
  - add/remove a dummy quota to generate an alert after <bytes> are seen including loopback.
    alerts are only triggered once.
    . ndc bandwidth setglobalalert <bytes>
       calling it multiple times, just re-arms the alert for the specified number of bytes.
        Use "ndc bandwidth getiquota singleAlert" to get what is left.
    . ndc bandwidth removeglobalalert
  - add/remove alert on a shared quota (similar accounting as shared quota)
    . ndc bandwidth setsharedalert <bytes>
        Requires that a shared quota already exist.
    . ndc bandwidth removesharedalert
        Removing the last of the shared quotas will remove the matching alert.
  - add/remove alert on an interface (similar accounting as interface quota)
    . ndc bandwidth setinterfacealert <iface> <bytes>
        Requires that a interface quota already exist.
    . ndc bandwidth removeinterfacealert <iface>
        Removing the interface quota will remove the matching alert.
  - get the quotas and alert leftovers
   . ndc bandwidth getquota
      shared quota leftover
   . ndc bandwidth getiquota <quota_name_or_iface>
      iface specific quota leftover
      Can be used to read-out alerts. E.g.
        setglobalalert 12345 -> getiquota globalAlert
        setsharedalert 12345 -> getiquota sharedAlert
        setinterfacealert iface0 12345 -> getiquota iface0Alert

Change-Id: Iea9698b9d20e713281755dac32b4772a6cf0e84e
diff --git a/BandwidthController.h b/BandwidthController.h
index f4fce50..70a4e1e 100644
--- a/BandwidthController.h
+++ b/BandwidthController.h
@@ -26,17 +26,34 @@
     int disableBandwidthControl(void);
 
     int setInterfaceSharedQuota(const char *iface, int64_t bytes);
+    int getInterfaceSharedQuota(int64_t *bytes);
     int removeInterfaceSharedQuota(const char *iface);
 
     int setInterfaceQuota(const char *iface, int64_t bytes);
+    int getInterfaceQuota(const char *iface, int64_t *bytes);
     int removeInterfaceQuota(const char *iface);
 
     int addNaughtyApps(int numUids, char *appUids[]);
     int removeNaughtyApps(int numUids, char *appUids[]);
 
+    int setGlobalAlert(int64_t bytes);
+    int removeGlobalAlert(void);
+
+    int setSharedAlert(int64_t bytes);
+    int removeSharedAlert(void);
+
+    int setInterfaceAlert(const char *iface, int64_t bytes);
+    int removeInterfaceAlert(const char *iface);
 
 protected:
-    typedef std::pair<std::string /*ifaceName*/, int64_t /*quota*/> QuotaInfo;
+    class QuotaInfo {
+    public:
+      QuotaInfo(std::string ifn, int64_t q, int64_t a)
+              : ifaceName(ifn), quota(q), alert(a) {};
+        std::string ifaceName;
+        int64_t quota;
+        int64_t alert;
+    };
     enum IptIpVer { IptIpV4, IptIpV6 };
     enum IptOp { IptOpInsert, IptOpReplace, IptOpDelete };
     enum IptRejectOp { IptRejectAdd, IptRejectNoAdd };
@@ -44,8 +61,9 @@
     enum QuotaType { QuotaUnique, QuotaShared };
     enum RunCmdErrHandling { RunCmdFailureBad, RunCmdFailureOk };
 
-    int64_t sharedQuotaBytes;
     std::list<std::string> sharedQuotaIfaces;
+    int64_t sharedQuotaBytes;
+    int64_t sharedAlertBytes;
 
     std::list<QuotaInfo> quotaIfaces;
 
@@ -58,6 +76,8 @@
     std::string makeIptablesNaughtyCmd(IptOp op, int uid);
     std::string makeIptablesQuotaCmd(IptOp op, const char *costName, int64_t quota);
 
+    int runIptablesAlertCmd(IptOp op, const char *alertName, int64_t bytes);
+
     /* Runs for both ipv4 and ipv6 iptables */
     int runCommands(int numCommands, const char *commands[], RunCmdErrHandling cmdErrHandling);
     /* Runs for both ipv4 and ipv6 iptables, appends -j REJECT --reject-with ...  */
@@ -67,6 +87,13 @@
     // Provides strncpy() + check overflow.
     static int StrncpyAndCheck(char *buffer, const char *src, size_t buffSize);
 
+    int updateQuota(const char *alertName, int64_t bytes);
+
+    int64_t globalAlertBytes;
+    int setCostlyAlert(const char *costName, int64_t bytes, int64_t *alertBytes);
+    int removeCostlyAlert(const char *costName, int64_t *alertBytes);
+
+
 private:
     static const char *cleanupCommands[];
     static const char *setupCommands[];
@@ -76,7 +103,8 @@
     static const int MAX_CMD_ARGS;
     static const char IPTABLES_PATH[];
     static const char IP6TABLES_PATH[];
-
+    static const char ALERT_IPT_TEMPLATE[];
+    static const int ALERT_RULE_POS_IN_COSTLY_CHAIN;
 };
 
 #endif