blob: bcd2ee67c647162077c6ae321a2154f40f15440a [file] [log] [blame]
San Mehat9d10b342010-01-18 09:51:02 -08001/*
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
Erik Kline70c03662016-03-31 11:39:53 +090020#include <list>
Lorenzo Colitti799625c2015-02-25 12:52:00 +090021#include <set>
22#include <string>
San Mehat9d10b342010-01-18 09:51:02 -080023
Lorenzo Colitti52db3912020-02-17 23:59:45 +090024#include <netdutils/DumpWriter.h>
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +090025#include <netdutils/StatusOr.h>
Lorenzo Colittia93126d2017-08-24 13:28:19 +090026#include <sysutils/SocketClient.h>
27
28#include "NetdConstants.h"
Lorenzo Colittie801d3c2020-02-18 00:00:35 +090029#include "android-base/result.h"
30#include "bpf/BpfMap.h"
31#include "netdbpf/bpf_shared.h"
Luke Huangd1ee4622018-06-29 13:49:58 +080032
Lorenzo Colittif0e051c2020-04-06 09:19:57 +000033#include "android/net/TetherOffloadRuleParcel.h"
34
Lorenzo Colittie20a5262017-05-09 18:30:44 +090035namespace android {
36namespace net {
San Mehat9d10b342010-01-18 09:51:02 -080037
38class TetherController {
waynema71a0b592018-11-21 13:31:34 +080039 private:
Remi NGUYEN VAN3b47c792018-03-20 14:44:12 +090040 struct ForwardingDownstream {
41 std::string iface;
42 bool active;
43 };
44
Erik Kline2c5aaa12016-06-08 13:24:45 +090045 std::list<std::string> mInterfaces;
Lorenzo Colittia93126d2017-08-24 13:28:19 +090046
Remi NGUYEN VAN3b47c792018-03-20 14:44:12 +090047 // 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
Luke Huang91bd3e12019-08-20 11:33:52 +080051 bool mIsTetheringStarted = false;
52
Lorenzo Colitti667c4772014-08-26 14:13:07 -070053 // 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.
Remi NGUYEN VAN7d9bebf2018-03-29 11:32:29 +090055 unsigned mDnsNetId = 0;
Erik Kline2c5aaa12016-06-08 13:24:45 +090056 std::list<std::string> mDnsForwarders;
Remi NGUYEN VAN7d9bebf2018-03-29 11:32:29 +090057 pid_t mDaemonPid = 0;
58 int mDaemonFd = -1;
Erik Kline2c5aaa12016-06-08 13:24:45 +090059 std::set<std::string> mForwardingRequests;
San Mehat9d10b342010-01-18 09:51:02 -080060
Erik Kline15079dd2018-05-18 23:10:56 +090061 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
Hungming Chenc2e95fb2020-02-19 17:41:30 +080075 // BPF maps, initialized by maybeInitMaps.
Lorenzo Colittie801d3c2020-02-18 00:00:35 +090076 bpf::BpfMap<TetherIngressKey, TetherIngressValue> mBpfIngressMap;
77 bpf::BpfMap<uint32_t, TetherStatsValue> mBpfStatsMap;
Maciej Żenczykowskid25a7342020-05-04 18:18:38 -070078 bpf::BpfMap<uint32_t, uint64_t> mBpfLimitMap;
Lorenzo Colittie801d3c2020-02-18 00:00:35 +090079
Erik Klineb31fd692018-06-06 20:50:11 +090080 public:
Sreeram Ramachandran87475a12014-07-15 16:20:28 -070081 TetherController();
Remi NGUYEN VAN7d9bebf2018-03-29 11:32:29 +090082 ~TetherController() = default;
San Mehat9d10b342010-01-18 09:51:02 -080083
Lorenzo Colitti799625c2015-02-25 12:52:00 +090084 bool enableForwarding(const char* requester);
85 bool disableForwarding(const char* requester);
Luke Huang728cf4c2019-03-14 19:43:02 +080086 const std::set<std::string>& getIpfwdRequesterList() const;
San Mehat9d10b342010-01-18 09:51:02 -080087
Luke Huang91bd3e12019-08-20 11:33:52 +080088 //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);
San Mehat9d10b342010-01-18 09:51:02 -080091 int stopTethering();
92 bool isTetheringStarted();
93
Lorenzo Colitti667c4772014-08-26 14:13:07 -070094 unsigned getDnsNetId();
95 int setDnsForwarders(unsigned netId, char **servers, int numServers);
Luke Huangb5733d72018-08-21 17:17:19 +080096 int setDnsForwarders(unsigned netId, const std::vector<std::string>& servers);
Erik Kline2c5aaa12016-06-08 13:24:45 +090097 const std::list<std::string> &getDnsForwarders() const;
San Mehat9d10b342010-01-18 09:51:02 -080098
99 int tetherInterface(const char *interface);
100 int untetherInterface(const char *interface);
Erik Kline2c5aaa12016-06-08 13:24:45 +0900101 const std::list<std::string> &getTetheredInterfaceList() const;
Erik Kline212c4052016-07-18 04:02:07 +0900102 bool applyDnsInterfaces();
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800103
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900104 int enableNat(const char* intIface, const char* extIface);
105 int disableNat(const char* intIface, const char* extIface);
106 int setupIptablesHooks();
107
Lorenzo Colittif0e051c2020-04-06 09:19:57 +0000108 base::Result<void> addOffloadRule(const TetherOffloadRuleParcel& rule);
109 base::Result<void> removeOffloadRule(const TetherOffloadRuleParcel& rule);
Lorenzo Colittie801d3c2020-02-18 00:00:35 +0900110
Hungming Chen93a39d22020-03-16 13:53:19 +0800111 int setTetherOffloadInterfaceQuota(int ifIndex, int64_t maxBytes);
112
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900113 class TetherStats {
waynema71a0b592018-11-21 13:31:34 +0800114 public:
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900115 TetherStats() = default;
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;
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900128
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
Hungming Chen41b0ed92020-06-02 00:13:20 +0000141 struct TetherOffloadStats {
142 int ifIndex;
143 int64_t rxBytes;
144 int64_t rxPackets;
145 int64_t txBytes;
146 int64_t txPackets;
147 };
148
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +0900149 typedef std::vector<TetherStats> TetherStatsList;
Hungming Chen41b0ed92020-06-02 00:13:20 +0000150 typedef std::vector<TetherOffloadStats> TetherOffloadStatsList;
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +0900151
Erik Klineb31fd692018-06-06 20:50:11 +0900152 netdutils::StatusOr<TetherStatsList> getTetherStats();
Hungming Chen41b0ed92020-06-02 00:13:20 +0000153 netdutils::StatusOr<TetherOffloadStatsList> getTetherOffloadStats();
Hungming Chenaf0dbed2020-04-17 20:00:27 +0800154 base::Result<TetherOffloadStats> getAndClearTetherOffloadStats(int ifIndex);
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900155
156 /*
Lorenzo Colitti09353392017-08-24 14:20:32 +0900157 * 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
Lorenzo Colitti4604b4a2017-08-24 19:21:50 +0900166 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";
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900171
Luke Huangd1ee4622018-06-29 13:49:58 +0800172 std::mutex lock;
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +0900173
Lorenzo Colitti52db3912020-02-17 23:59:45 +0900174 void dump(netdutils::DumpWriter& dw);
175 void dumpIfaces(netdutils::DumpWriter& dw);
Lorenzo Colittie801d3c2020-02-18 00:00:35 +0900176 void dumpBpf(netdutils::DumpWriter& dw);
Lorenzo Colitti52db3912020-02-17 23:59:45 +0900177
waynema71a0b592018-11-21 13:31:34 +0800178 private:
Lorenzo Colitti799625c2015-02-25 12:52:00 +0900179 bool setIpFwdEnabled();
Luke Huangb5733d72018-08-21 17:17:19 +0800180 std::vector<char*> toCstrVec(const std::vector<std::string>& addrs);
Remi NGUYEN VAN3b47c792018-03-20 14:44:12 +0900181 int setupIPv6CountersChain();
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900182 static std::string makeTetherCountingRule(const char *if1, const char *if2);
Remi NGUYEN VAN3b47c792018-03-20 14:44:12 +0900183 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);
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900192
193 int setDefaults();
Luke Huangae038f82018-11-05 11:17:31 +0900194 int setTetherGlobalAlertRule();
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900195 int setForwardRules(bool set, const char *intIface, const char *extIface);
196 int setTetherCountingRules(bool add, const char *intIface, const char *extIface);
197
Maciej Żenczykowskiac14cb52020-05-23 20:48:00 +0000198 base::Result<void> setBpfLimit(uint32_t ifIndex, uint64_t limit);
Hungming Chenc2e95fb2020-02-19 17:41:30 +0800199 void maybeInitMaps();
Hungming Chen1da90082020-02-14 20:24:16 +0800200 void maybeStartBpf(const char* extIface);
201 void maybeStopBpf(const char* extIface);
202
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +0900203 static void addStats(TetherStatsList& statsList, const TetherStats& stats);
204
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900205 // For testing.
206 friend class TetherControllerTest;
207 static int (*iptablesRestoreFunction)(IptablesTarget, const std::string&, std::string *);
San Mehat9d10b342010-01-18 09:51:02 -0800208};
209
Lorenzo Colittie20a5262017-05-09 18:30:44 +0900210} // namespace net
211} // namespace android
212
San Mehat9d10b342010-01-18 09:51:02 -0800213#endif