Move all tethering functionality into TetherController.

This includes the entirety of NatController and relevant
parts of BandwidthController (specifically, getTetherStats
and its dependencies).

This will make the code easier to understand and allow netd to
privide a simpler API to the framework (e.g., by providing
higher-level methods that perform what today are multiple
operations from the framework's point of view).

It will also reduce duplication of state (e.g., interface pairs
kept by NatController partially overlap with downstream
interfaces kept by TetherController) and avoid dependencies
between controllers.

This CL makes no functional changes. The only code changes are
the ones necessary for compilation. Specifically:
- Move some methods into IptablesBaseTest.cpp so they can be
  used from two test classes.
- Change TetherController::iptablesRestoreFunction to the
  three-argument used by the erstwhile BandwidthController
  tests.

Where appropriate, variable names have been changed, but strings
that actually appear on device, such as iptables rule names, are
left as is and will be changed in a future CL.

Bug: 32163131
Bug: 64995262
Test: bullhead builds, boots
Test: netd_{unit,integration}_test pass
Change-Id: Idc80bfd424ce011826305f84b1cc98e741698601
diff --git a/server/TetherController.h b/server/TetherController.h
index 13da05c..4ed94ee 100644
--- a/server/TetherController.h
+++ b/server/TetherController.h
@@ -17,18 +17,21 @@
 #ifndef _TETHER_CONTROLLER_H
 #define _TETHER_CONTROLLER_H
 
-#include <netinet/in.h>
-
 #include <list>
 #include <set>
 #include <string>
 
+#include <sysutils/SocketClient.h>
+
+#include "NetdConstants.h"
+
 namespace android {
 namespace net {
 
 class TetherController {
 private:
     std::list<std::string> mInterfaces;
+
     // NetId to use for forwarded DNS queries. This may not be the default
     // network, e.g., in the case where we are tethering to a DUN APN.
     unsigned               mDnsNetId;
@@ -38,9 +41,14 @@
     std::set<std::string>  mForwardingRequests;
 
 public:
+
     TetherController();
     virtual ~TetherController();
 
+    // List of strings of interface pairs. Public because it's used by CommandListener.
+    // TODO: merge with mInterfaces, and make private.
+    std::list<std::string> ifacePairList;
+
     bool enableForwarding(const char* requester);
     bool disableForwarding(const char* requester);
     size_t forwardingRequestCount();
@@ -58,8 +66,91 @@
     const std::list<std::string> &getTetheredInterfaceList() const;
     bool applyDnsInterfaces();
 
+    int enableNat(const char* intIface, const char* extIface);
+    int disableNat(const char* intIface, const char* extIface);
+    int setupIptablesHooks();
+
+    class TetherStats {
+    public:
+        TetherStats() = default;
+        TetherStats(std::string intIfn, std::string extIfn,
+                int64_t rxB, int64_t rxP,
+                int64_t txB, int64_t txP)
+                        : intIface(intIfn), extIface(extIfn),
+                            rxBytes(rxB), rxPackets(rxP),
+                            txBytes(txB), txPackets(txP) {};
+        std::string intIface;
+        std::string extIface;
+        int64_t rxBytes = -1;
+        int64_t rxPackets = -1;
+        int64_t txBytes = -1;
+        int64_t txPackets = -1;
+        /*
+         * Returns a new string representing this:
+         * intIface extIface rx_bytes rx_packets tx_bytes tx_packets
+         */
+        std::string getStatsLine() const;
+
+        bool addStatsIfMatch(const TetherStats& other) {
+            if (intIface == other.intIface && extIface == other.extIface) {
+                rxBytes   += other.rxBytes;
+                rxPackets += other.rxPackets;
+                txBytes   += other.txBytes;
+                txPackets += other.txPackets;
+                return true;
+            }
+            return false;
+        }
+    };
+
+    /*
+     * For single pair of ifaces, stats should have ifaceIn and ifaceOut initialized.
+     * For all pairs, stats should have ifaceIn=ifaceOut="".
+     * Sends out to the cli the single stat (TetheringStatsReluts) or a list of stats
+     * (TetheringStatsListResult+CommandOkay).
+     * Error is to be handled on the outside.
+     * It results in an error if invoked and no tethering counter rules exist.
+     */
+    int getTetherStats(SocketClient *cli, TetherStats &stats, std::string &extraProcessingInfo);
+
+    typedef std::vector<TetherStats> TetherStatsList;
+
+    static void addStats(TetherStatsList& statsList, const TetherStats& stats);
+
+    /*
+     * stats should never have only intIface initialized. Other 3 combos are ok.
+     * fp should be a file to the apropriate FORWARD chain of iptables rules.
+     * extraProcessingInfo: contains raw parsed data, and error info.
+     * This strongly requires that setup of the rules is in a specific order:
+     *  in:intIface out:extIface
+     *  in:extIface out:intIface
+     * and the rules are grouped in pairs when more that one tethering was setup.
+     */
+    static int addForwardChainStats(const TetherStats& filter,
+                                    TetherStatsList& statsList, const std::string& iptOutput,
+                                    std::string &extraProcessingInfo);
+
+    static constexpr const char* LOCAL_FORWARD               = "natctrl_FORWARD";
+    static constexpr const char* LOCAL_MANGLE_FORWARD        = "natctrl_mangle_FORWARD";
+    static constexpr const char* LOCAL_NAT_POSTROUTING       = "natctrl_nat_POSTROUTING";
+    static constexpr const char* LOCAL_RAW_PREROUTING        = "natctrl_raw_PREROUTING";
+    static constexpr const char* LOCAL_TETHER_COUNTERS_CHAIN = "natctrl_tether_counters";
+
 private:
     bool setIpFwdEnabled();
+
+    int natCount;
+
+    static std::string makeTetherCountingRule(const char *if1, const char *if2);
+    bool checkTetherCountingRuleExist(const std::string& pair_name);
+
+    int setDefaults();
+    int setForwardRules(bool set, const char *intIface, const char *extIface);
+    int setTetherCountingRules(bool add, const char *intIface, const char *extIface);
+
+    // For testing.
+    friend class TetherControllerTest;
+    static int (*iptablesRestoreFunction)(IptablesTarget, const std::string&, std::string *);
 };
 
 }  // namespace net