1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef _TETHER_CONTROLLER_H
18 #define _TETHER_CONTROLLER_H
19 
20 #include <list>
21 #include <set>
22 #include <string>
23 
24 #include <netdutils/DumpWriter.h>
25 #include <netdutils/StatusOr.h>
26 #include <sysutils/SocketClient.h>
27 
28 #include "NetdConstants.h"
29 #include "android-base/result.h"
30 #include "bpf/BpfMap.h"
31 #include "netdbpf/bpf_shared.h"
32 
33 #include "android/net/TetherOffloadRuleParcel.h"
34 
35 namespace android {
36 namespace net {
37 
38 class TetherController {
39   private:
40     struct ForwardingDownstream {
41         std::string iface;
42         bool active;
43     };
44 
45     std::list<std::string> mInterfaces;
46 
47     // Map upstream iface -> downstream iface. A pair is in the map if forwarding was enabled at
48     // some point since the controller was initialized.
49     std::multimap<std::string, ForwardingDownstream> mFwdIfaces;
50 
51     bool mIsTetheringStarted = false;
52 
53     // NetId to use for forwarded DNS queries. This may not be the default
54     // network, e.g., in the case where we are tethering to a DUN APN.
55     unsigned               mDnsNetId = 0;
56     std::list<std::string> mDnsForwarders;
57     pid_t                  mDaemonPid = 0;
58     int                    mDaemonFd = -1;
59     std::set<std::string>  mForwardingRequests;
60 
61     struct DnsmasqState {
62         static int sendCmd(int daemonFd, const std::string& cmd);
63 
64         // List of downstream interfaces on which to serve. The format used is:
65         //     update_ifaces|<ifname1>|<ifname2>|...
66         std::string update_ifaces_cmd;
67         // Forwarding (upstream) DNS configuration to use. The format used is:
68         //     update_dns|<hex_socket_mark>|<ip1>|<ip2>|...
69         std::string update_dns_cmd;
70 
71         void clear();
72         int sendAllState(int daemonFd) const;
73     } mDnsmasqState{};
74 
75     // BPF maps, initialized by maybeInitMaps.
76     bpf::BpfMap<TetherIngressKey, TetherIngressValue> mBpfIngressMap;
77     bpf::BpfMap<uint32_t, TetherStatsValue> mBpfStatsMap;
78     bpf::BpfMap<uint32_t, uint64_t> mBpfLimitMap;
79 
80   public:
81     TetherController();
82     ~TetherController() = default;
83 
84     bool enableForwarding(const char* requester);
85     bool disableForwarding(const char* requester);
86     const std::set<std::string>& getIpfwdRequesterList() const;
87 
88     //TODO: Clean up the overload function
89     int startTethering(bool isLegacyDnsProxy, int num_addrs, char** dhcp_ranges);
90     int startTethering(bool isLegacyDnsProxy, const std::vector<std::string>& dhcpRanges);
91     int stopTethering();
92     bool isTetheringStarted();
93 
94     unsigned getDnsNetId();
95     int setDnsForwarders(unsigned netId, char **servers, int numServers);
96     int setDnsForwarders(unsigned netId, const std::vector<std::string>& servers);
97     const std::list<std::string> &getDnsForwarders() const;
98 
99     int tetherInterface(const char *interface);
100     int untetherInterface(const char *interface);
101     const std::list<std::string> &getTetheredInterfaceList() const;
102     bool applyDnsInterfaces();
103 
104     int enableNat(const char* intIface, const char* extIface);
105     int disableNat(const char* intIface, const char* extIface);
106     int setupIptablesHooks();
107 
108     base::Result<void> addOffloadRule(const TetherOffloadRuleParcel& rule);
109     base::Result<void> removeOffloadRule(const TetherOffloadRuleParcel& rule);
110 
111     int setTetherOffloadInterfaceQuota(int ifIndex, int64_t maxBytes);
112 
113     class TetherStats {
114       public:
115         TetherStats() = default;
TetherStats(std::string intIfn,std::string extIfn,int64_t rxB,int64_t rxP,int64_t txB,int64_t txP)116         TetherStats(std::string intIfn, std::string extIfn,
117                 int64_t rxB, int64_t rxP,
118                 int64_t txB, int64_t txP)
119                         : intIface(intIfn), extIface(extIfn),
120                             rxBytes(rxB), rxPackets(rxP),
121                             txBytes(txB), txPackets(txP) {};
122         std::string intIface;
123         std::string extIface;
124         int64_t rxBytes = -1;
125         int64_t rxPackets = -1;
126         int64_t txBytes = -1;
127         int64_t txPackets = -1;
128 
addStatsIfMatch(const TetherStats & other)129         bool addStatsIfMatch(const TetherStats& other) {
130             if (intIface == other.intIface && extIface == other.extIface) {
131                 rxBytes   += other.rxBytes;
132                 rxPackets += other.rxPackets;
133                 txBytes   += other.txBytes;
134                 txPackets += other.txPackets;
135                 return true;
136             }
137             return false;
138         }
139     };
140 
141     struct TetherOffloadStats {
142         int ifIndex;
143         int64_t rxBytes;
144         int64_t rxPackets;
145         int64_t txBytes;
146         int64_t txPackets;
147     };
148 
149     typedef std::vector<TetherStats> TetherStatsList;
150     typedef std::vector<TetherOffloadStats> TetherOffloadStatsList;
151 
152     netdutils::StatusOr<TetherStatsList> getTetherStats();
153     netdutils::StatusOr<TetherOffloadStatsList> getTetherOffloadStats();
154     base::Result<TetherOffloadStats> getAndClearTetherOffloadStats(int ifIndex);
155 
156     /*
157      * extraProcessingInfo: contains raw parsed data, and error info.
158      * This strongly requires that setup of the rules is in a specific order:
159      *  in:intIface out:extIface
160      *  in:extIface out:intIface
161      * and the rules are grouped in pairs when more that one tethering was setup.
162      */
163     static int addForwardChainStats(TetherStatsList& statsList, const std::string& iptOutput,
164                                     std::string &extraProcessingInfo);
165 
166     static constexpr const char* LOCAL_FORWARD               = "tetherctrl_FORWARD";
167     static constexpr const char* LOCAL_MANGLE_FORWARD        = "tetherctrl_mangle_FORWARD";
168     static constexpr const char* LOCAL_NAT_POSTROUTING       = "tetherctrl_nat_POSTROUTING";
169     static constexpr const char* LOCAL_RAW_PREROUTING        = "tetherctrl_raw_PREROUTING";
170     static constexpr const char* LOCAL_TETHER_COUNTERS_CHAIN = "tetherctrl_counters";
171 
172     std::mutex lock;
173 
174     void dump(netdutils::DumpWriter& dw);
175     void dumpIfaces(netdutils::DumpWriter& dw);
176     void dumpBpf(netdutils::DumpWriter& dw);
177 
178   private:
179     bool setIpFwdEnabled();
180     std::vector<char*> toCstrVec(const std::vector<std::string>& addrs);
181     int setupIPv6CountersChain();
182     static std::string makeTetherCountingRule(const char *if1, const char *if2);
183     ForwardingDownstream* findForwardingDownstream(const std::string& intIface,
184         const std::string& extIface);
185     void addForwardingPair(const std::string& intIface, const std::string& extIface);
186     void markForwardingPairDisabled(const std::string& intIface, const std::string& extIface);
187 
188     bool isForwardingPairEnabled(const std::string& intIface, const std::string& extIface);
189     bool isAnyForwardingEnabledOnUpstream(const std::string& extIface);
190     bool isAnyForwardingPairEnabled();
191     bool tetherCountingRuleExists(const std::string& iface1, const std::string& iface2);
192 
193     int setDefaults();
194     int setTetherGlobalAlertRule();
195     int setForwardRules(bool set, const char *intIface, const char *extIface);
196     int setTetherCountingRules(bool add, const char *intIface, const char *extIface);
197 
198     base::Result<void> setBpfLimit(uint32_t ifIndex, uint64_t limit);
199     void maybeInitMaps();
200     void maybeStartBpf(const char* extIface);
201     void maybeStopBpf(const char* extIface);
202 
203     static void addStats(TetherStatsList& statsList, const TetherStats& stats);
204 
205     // For testing.
206     friend class TetherControllerTest;
207     static int (*iptablesRestoreFunction)(IptablesTarget, const std::string&, std::string *);
208 };
209 
210 }  // namespace net
211 }  // namespace android
212 
213 #endif
214