blob: 1bb3c3ac0cdada4f2c7e05de2a3c5317b12ffb75 [file] [log] [blame]
San Mehat873f2142010-01-14 10:25:07 -08001/*
2 * Copyright (C) 2007 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
17package com.android.server;
18
paulhu79ebe4f2019-12-06 16:45:38 +080019import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
Sehee Parka9139bc2017-12-22 13:54:05 +090020import static android.Manifest.permission.NETWORK_SETTINGS;
paulhu59148b72019-08-12 16:25:11 +080021import static android.Manifest.permission.OBSERVE_NETWORK_POLICY;
Jeff Sharkeyaf75c332011-11-18 12:41:12 -080022import static android.Manifest.permission.SHUTDOWN;
Remi NGUYEN VANf9a8c2e2019-02-13 18:28:35 +090023import static android.net.INetd.FIREWALL_BLACKLIST;
24import static android.net.INetd.FIREWALL_CHAIN_DOZABLE;
25import static android.net.INetd.FIREWALL_CHAIN_NONE;
26import static android.net.INetd.FIREWALL_CHAIN_POWERSAVE;
27import static android.net.INetd.FIREWALL_CHAIN_STANDBY;
28import static android.net.INetd.FIREWALL_RULE_ALLOW;
29import static android.net.INetd.FIREWALL_RULE_DENY;
30import static android.net.INetd.FIREWALL_WHITELIST;
Xiaohui Chenb41c9f72015-06-17 15:55:37 -070031import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_DOZABLE;
Felipe Leme011b98f2016-02-10 17:28:31 -080032import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_POWERSAVE;
Xiaohui Chenb41c9f72015-06-17 15:55:37 -070033import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_STANDBY;
Xiaohui Chenb41c9f72015-06-17 15:55:37 -070034import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -070035import static android.net.NetworkStats.SET_DEFAULT;
Lorenzo Colittif1912ca2017-08-17 19:23:08 +090036import static android.net.NetworkStats.STATS_PER_UID;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -070037import static android.net.NetworkStats.TAG_NONE;
Jeff Sharkeyae2c1812011-10-04 13:11:40 -070038import static android.net.TrafficStats.UID_TETHERING;
Lorenzo Colitti9307ca22019-01-12 01:54:23 +090039
Jeff Sharkeya63ba592011-07-19 23:47:12 -070040import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED;
Erik Klineb2cfdfb2017-01-18 20:54:14 +090041
Xiaohui Chenb41c9f72015-06-17 15:55:37 -070042import android.annotation.NonNull;
Sudheer Shankadc589ac2016-11-10 15:30:17 -080043import android.app.ActivityManager;
San Mehat873f2142010-01-14 10:25:07 -080044import android.content.Context;
Dianne Hackborn77b987f2014-02-26 16:20:52 -080045import android.net.ConnectivityManager;
Lorenzo Colitti58967ba2016-02-02 17:21:21 +090046import android.net.INetd;
Remi NGUYEN VAN9ebc3fc2019-01-29 19:12:13 +090047import android.net.INetdUnsolicitedEventListener;
San Mehat4d02d002010-01-22 16:07:46 -080048import android.net.INetworkManagementEventObserver;
Lorenzo Colitti07f13042017-07-10 19:06:57 +090049import android.net.ITetheringStatsProvider;
Remi NGUYEN VAN9ebc3fc2019-01-29 19:12:13 +090050import android.net.InetAddresses;
Jeff Sharkeyeedcb952011-05-17 14:55:15 -070051import android.net.InterfaceConfiguration;
Luke Huang14f75442018-08-15 19:22:54 +080052import android.net.InterfaceConfigurationParcel;
Lorenzo Colittic18cbfd2014-06-13 21:21:03 +090053import android.net.IpPrefix;
Robert Greenwalted126402011-01-28 15:34:55 -080054import android.net.LinkAddress;
Lorenzo Colittib57edc52014-08-22 17:10:50 -070055import android.net.Network;
Amith Yamasani15e472352015-04-24 19:06:07 -070056import android.net.NetworkPolicyManager;
paulhu59148b72019-08-12 16:25:11 +080057import android.net.NetworkStack;
Jeff Sharkeyeedcb952011-05-17 14:55:15 -070058import android.net.NetworkStats;
Robert Greenwalted126402011-01-28 15:34:55 -080059import android.net.NetworkUtils;
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -070060import android.net.RouteInfo;
Lorenzo Colitti9307ca22019-01-12 01:54:23 +090061import android.net.TetherStatsParcel;
Paul Jensen6bc2c2c2014-05-07 15:27:40 -040062import android.net.UidRange;
Lorenzo Colitticc7f1db2019-03-18 23:50:34 +090063import android.net.UidRangeParcel;
markchiena9d9ef82020-01-07 14:43:17 +080064import android.net.shared.NetdUtils;
65import android.net.shared.RouteUtils;
66import android.net.shared.RouteUtils.ModifyOperation;
Remi NGUYEN VAN231b52b2019-01-29 15:38:52 +090067import android.net.util.NetdService;
Dianne Hackborn91268cf2013-06-13 19:06:50 -070068import android.os.BatteryStats;
Jeff Sharkeyf56e2432012-09-06 17:54:29 -070069import android.os.Binder;
Jeff Sharkeyb24a7852012-05-01 15:19:37 -070070import android.os.Handler;
Lorenzo Colittia0868002017-07-11 02:29:28 +090071import android.os.IBinder;
Dianne Hackborn77b987f2014-02-26 16:20:52 -080072import android.os.INetworkActivityListener;
San Mehat873f2142010-01-14 10:25:07 -080073import android.os.INetworkManagementService;
Jeff Sharkeyf56e2432012-09-06 17:54:29 -070074import android.os.Process;
Jeff Sharkey3df273e2011-12-15 15:47:12 -080075import android.os.RemoteCallbackList;
76import android.os.RemoteException;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070077import android.os.ServiceManager;
Lorenzo Colitti4cb42402016-04-24 12:52:00 +090078import android.os.ServiceSpecificException;
Jeff Sharkey605eb792014-11-04 13:34:06 -080079import android.os.StrictMode;
Jeff Sharkey9a13f362011-04-26 16:25:36 -070080import android.os.SystemClock;
Marco Nelissen62dbb222010-02-18 10:56:30 -080081import android.os.SystemProperties;
Felipe Leme29e72ea2016-09-08 13:26:55 -070082import android.os.Trace;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070083import android.telephony.DataConnectionRealTimeInfo;
Lorenzo Colitticc7f1db2019-03-18 23:50:34 +090084import android.text.TextUtils;
Irfan Sheriff9ab518ad2010-03-12 15:48:17 -080085import android.util.Log;
Joe Onorato8a9b2202010-02-26 18:56:32 -080086import android.util.Slog;
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -070087import android.util.SparseBooleanArray;
Jeff Sharkey605eb792014-11-04 13:34:06 -080088import android.util.SparseIntArray;
San Mehat873f2142010-01-14 10:25:07 -080089
Jeff Sharkey605eb792014-11-04 13:34:06 -080090import com.android.internal.annotations.GuardedBy;
Sudheer Shanka62f5c172017-03-17 16:25:55 -070091import com.android.internal.annotations.VisibleForTesting;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070092import com.android.internal.app.IBatteryStats;
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -060093import com.android.internal.util.DumpUtils;
Muhammad Qureshi93891dd2020-01-28 10:08:24 -080094import com.android.internal.util.FrameworkStatsLog;
Jeff Sharkey605eb792014-11-04 13:34:06 -080095import com.android.internal.util.HexDump;
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -070096import com.android.internal.util.Preconditions;
Lorenzo Colitti9307ca22019-01-12 01:54:23 +090097
Jeff Sharkeyb24a7852012-05-01 15:19:37 -070098import com.google.android.collect.Maps;
Jeff Sharkey4414cea2011-06-24 17:05:24 -070099
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700100import java.io.BufferedReader;
101import java.io.DataInputStream;
Jeff Sharkey47eb1022011-08-25 17:48:52 -0700102import java.io.FileDescriptor;
Jeff Sharkey9a13f362011-04-26 16:25:36 -0700103import java.io.FileInputStream;
Jeff Sharkey9a13f362011-04-26 16:25:36 -0700104import java.io.IOException;
Jeff Sharkey9a13f362011-04-26 16:25:36 -0700105import java.io.InputStreamReader;
Jeff Sharkey47eb1022011-08-25 17:48:52 -0700106import java.io.PrintWriter;
Jeff Sharkeyeedcb952011-05-17 14:55:15 -0700107import java.net.InetAddress;
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -0700108import java.net.InterfaceAddress;
Jeff Sharkeyeedcb952011-05-17 14:55:15 -0700109import java.util.ArrayList;
Paul Jensen6bc2c2c2014-05-07 15:27:40 -0400110import java.util.Arrays;
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700111import java.util.HashMap;
jiaguo1da35f72014-01-09 16:39:59 +0800112import java.util.List;
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700113import java.util.Map;
Daulet Zhanguzinea1a7ca2020-01-03 09:46:50 +0000114import java.util.Objects;
San Mehat873f2142010-01-14 10:25:07 -0800115
116/**
117 * @hide
118 */
Luke Huang909b31a2019-03-16 21:21:16 +0800119public class NetworkManagementService extends INetworkManagementService.Stub {
Lorenzo Colittia0868002017-07-11 02:29:28 +0900120
121 /**
122 * Helper class that encapsulates NetworkManagementService dependencies and makes them
123 * easier to mock in unit tests.
124 */
125 static class SystemServices {
126 public IBinder getService(String name) {
127 return ServiceManager.getService(name);
128 }
129 public void registerLocalService(NetworkManagementInternal nmi) {
130 LocalServices.addService(NetworkManagementInternal.class, nmi);
131 }
132 public INetd getNetd() {
133 return NetdService.get();
134 }
135 }
136
Amith Yamasani15e472352015-04-24 19:06:07 -0700137 private static final String TAG = "NetworkManagement";
138 private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
Kenny Root305bcbf2010-09-03 07:56:38 -0700139
Paul Jensen6bc2c2c2014-05-07 15:27:40 -0400140 private static final int MAX_UID_RANGES_PER_COMMAND = 10;
141
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700142 /**
143 * Name representing {@link #setGlobalAlert(long)} limit when delivered to
144 * {@link INetworkManagementEventObserver#limitReached(String, String)}.
145 */
146 public static final String LIMIT_GLOBAL_ALERT = "globalAlert";
147
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700148 static final int DAEMON_MSG_MOBILE_CONN_REAL_TIME_INFO = 1;
149
Luke Huang8a462ec2018-08-24 20:33:16 +0800150 static final boolean MODIFY_OPERATION_ADD = true;
151 static final boolean MODIFY_OPERATION_REMOVE = false;
152
San Mehat873f2142010-01-14 10:25:07 -0800153 /**
154 * Binder context for this service
155 */
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700156 private final Context mContext;
San Mehat873f2142010-01-14 10:25:07 -0800157
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700158 private final Handler mDaemonHandler;
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700159
Lorenzo Colittia0868002017-07-11 02:29:28 +0900160 private final SystemServices mServices;
161
Lorenzo Colitti58967ba2016-02-02 17:21:21 +0900162 private INetd mNetdService;
163
Remi NGUYEN VAN9ebc3fc2019-01-29 19:12:13 +0900164 private final NetdUnsolicitedEventListener mNetdUnsolicitedEventListener;
Luke Huangd290dd52018-09-04 17:08:18 +0800165
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800166 private IBatteryStats mBatteryStats;
167
Remi NGUYEN VAN9ebc3fc2019-01-29 19:12:13 +0900168 private final RemoteCallbackList<INetworkManagementEventObserver> mObservers =
169 new RemoteCallbackList<>();
170
Lorenzo Colitti07f13042017-07-10 19:06:57 +0900171 @GuardedBy("mTetheringStatsProviders")
172 private final HashMap<ITetheringStatsProvider, String>
173 mTetheringStatsProviders = Maps.newHashMap();
174
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700175 /**
176 * If both locks need to be held, then they should be obtained in the order:
177 * first {@link #mQuotaLock} and then {@link #mRulesLock}.
178 */
Andrew Scull45f533c2017-05-19 15:37:20 +0100179 private final Object mQuotaLock = new Object();
Andrew Scull519291f2017-05-23 13:11:03 +0100180 private final Object mRulesLock = new Object();
Jeff Sharkey605eb792014-11-04 13:34:06 -0800181
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -0700182 /** Set of interfaces with active quotas. */
Jeff Sharkey605eb792014-11-04 13:34:06 -0800183 @GuardedBy("mQuotaLock")
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700184 private HashMap<String, Long> mActiveQuotas = Maps.newHashMap();
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700185 /** Set of interfaces with active alerts. */
Jeff Sharkey605eb792014-11-04 13:34:06 -0800186 @GuardedBy("mQuotaLock")
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700187 private HashMap<String, Long> mActiveAlerts = Maps.newHashMap();
Felipe Leme65be3022016-03-22 14:53:13 -0700188 /** Set of UIDs blacklisted on metered networks. */
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700189 @GuardedBy("mRulesLock")
Felipe Leme65be3022016-03-22 14:53:13 -0700190 private SparseBooleanArray mUidRejectOnMetered = new SparseBooleanArray();
191 /** Set of UIDs whitelisted on metered networks. */
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700192 @GuardedBy("mRulesLock")
Felipe Leme65be3022016-03-22 14:53:13 -0700193 private SparseBooleanArray mUidAllowOnMetered = new SparseBooleanArray();
Jeff Sharkey605eb792014-11-04 13:34:06 -0800194 /** Set of UIDs with cleartext penalties. */
195 @GuardedBy("mQuotaLock")
196 private SparseIntArray mUidCleartextPolicy = new SparseIntArray();
Amith Yamasani15e472352015-04-24 19:06:07 -0700197 /** Set of UIDs that are to be blocked/allowed by firewall controller. */
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700198 @GuardedBy("mRulesLock")
Amith Yamasani15e472352015-04-24 19:06:07 -0700199 private SparseIntArray mUidFirewallRules = new SparseIntArray();
Xiaohui Chenb41c9f72015-06-17 15:55:37 -0700200 /**
201 * Set of UIDs that are to be blocked/allowed by firewall controller. This set of Ids matches
202 * to application idles.
203 */
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700204 @GuardedBy("mRulesLock")
Xiaohui Chenb41c9f72015-06-17 15:55:37 -0700205 private SparseIntArray mUidFirewallStandbyRules = new SparseIntArray();
206 /**
207 * Set of UIDs that are to be blocked/allowed by firewall controller. This set of Ids matches
208 * to device idles.
209 */
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700210 @GuardedBy("mRulesLock")
Xiaohui Chenb41c9f72015-06-17 15:55:37 -0700211 private SparseIntArray mUidFirewallDozableRules = new SparseIntArray();
Felipe Leme011b98f2016-02-10 17:28:31 -0800212 /**
213 * Set of UIDs that are to be blocked/allowed by firewall controller. This set of Ids matches
214 * to device on power-save mode.
215 */
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700216 @GuardedBy("mRulesLock")
Felipe Leme011b98f2016-02-10 17:28:31 -0800217 private SparseIntArray mUidFirewallPowerSaveRules = new SparseIntArray();
Xiaohui Chen8dca36d2015-06-19 12:44:59 -0700218 /** Set of states for the child firewall chains. True if the chain is active. */
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700219 @GuardedBy("mRulesLock")
Xiaohui Chen8dca36d2015-06-19 12:44:59 -0700220 final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray();
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -0700221
Felipe Leme65be3022016-03-22 14:53:13 -0700222 @GuardedBy("mQuotaLock")
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700223 private volatile boolean mDataSaverMode;
Felipe Leme65be3022016-03-22 14:53:13 -0700224
Andrew Scull45f533c2017-05-19 15:37:20 +0100225 private final Object mIdleTimerLock = new Object();
Haoyu Bai04124232012-06-28 15:26:19 -0700226 /** Set of interfaces with active idle timers. */
227 private static class IdleTimerParams {
228 public final int timeout;
Dianne Hackborn77b987f2014-02-26 16:20:52 -0800229 public final int type;
Haoyu Bai04124232012-06-28 15:26:19 -0700230 public int networkCount;
231
Dianne Hackborn77b987f2014-02-26 16:20:52 -0800232 IdleTimerParams(int timeout, int type) {
Haoyu Bai04124232012-06-28 15:26:19 -0700233 this.timeout = timeout;
Dianne Hackborn77b987f2014-02-26 16:20:52 -0800234 this.type = type;
Haoyu Bai04124232012-06-28 15:26:19 -0700235 this.networkCount = 1;
236 }
237 }
238 private HashMap<String, IdleTimerParams> mActiveIdleTimers = Maps.newHashMap();
239
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -0700240 private volatile boolean mFirewallEnabled;
Jeff Sharkey605eb792014-11-04 13:34:06 -0800241 private volatile boolean mStrictEnabled;
Jeff Sharkey350083e2011-06-29 10:45:16 -0700242
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700243 private boolean mMobileActivityFromRadio = false;
244 private int mLastPowerStateFromRadio = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
Adam Lesinskie08af192015-03-25 16:42:59 -0700245 private int mLastPowerStateFromWifi = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700246
Dianne Hackborn77b987f2014-02-26 16:20:52 -0800247 private final RemoteCallbackList<INetworkActivityListener> mNetworkActivityListeners =
Christopher Wiley212b95f2016-08-02 11:38:57 -0700248 new RemoteCallbackList<>();
Dianne Hackborn77b987f2014-02-26 16:20:52 -0800249 private boolean mNetworkActive;
250
San Mehat873f2142010-01-14 10:25:07 -0800251 /**
252 * Constructs a new NetworkManagementService instance
253 *
254 * @param context Binder context for this service
255 */
Lorenzo Colittia0868002017-07-11 02:29:28 +0900256 private NetworkManagementService(
Luke Huang909b31a2019-03-16 21:21:16 +0800257 Context context, SystemServices services) {
San Mehat873f2142010-01-14 10:25:07 -0800258 mContext = context;
Lorenzo Colittia0868002017-07-11 02:29:28 +0900259 mServices = services;
San Mehat4d02d002010-01-22 16:07:46 -0800260
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700261 mDaemonHandler = new Handler(FgThread.get().getLooper());
Wink Saville67e07892014-06-18 16:43:14 -0700262
Remi NGUYEN VAN9ebc3fc2019-01-29 19:12:13 +0900263 mNetdUnsolicitedEventListener = new NetdUnsolicitedEventListener();
264
Lorenzo Colittia0868002017-07-11 02:29:28 +0900265 mServices.registerLocalService(new LocalService());
Lorenzo Colitti8228eb32017-07-19 06:17:33 +0900266
Lorenzo Colitti07f13042017-07-10 19:06:57 +0900267 synchronized (mTetheringStatsProviders) {
268 mTetheringStatsProviders.put(new NetdTetheringStatsProvider(), "netd");
269 }
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700270 }
271
272 @VisibleForTesting
273 NetworkManagementService() {
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700274 mContext = null;
275 mDaemonHandler = null;
Lorenzo Colittia0868002017-07-11 02:29:28 +0900276 mServices = null;
Remi NGUYEN VAN9ebc3fc2019-01-29 19:12:13 +0900277 mNetdUnsolicitedEventListener = null;
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700278 }
279
Luke Huang909b31a2019-03-16 21:21:16 +0800280 static NetworkManagementService create(Context context, SystemServices services)
Felipe Leme03e689d2016-03-02 16:17:38 -0800281 throws InterruptedException {
Lorenzo Colittia0868002017-07-11 02:29:28 +0900282 final NetworkManagementService service =
Luke Huang909b31a2019-03-16 21:21:16 +0800283 new NetworkManagementService(context, services);
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700284 if (DBG) Slog.d(TAG, "Creating NetworkManagementService");
Lorenzo Colitti8c253ad2017-07-19 00:23:44 +0900285 if (DBG) Slog.d(TAG, "Connecting native netd service");
bohu07cc3bb2016-05-03 15:58:01 -0700286 service.connectNativeNetdService();
Lorenzo Colitti8c253ad2017-07-19 00:23:44 +0900287 if (DBG) Slog.d(TAG, "Connected");
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700288 return service;
San Mehat873f2142010-01-14 10:25:07 -0800289 }
290
Lorenzo Colitti7421a012013-08-20 22:51:24 +0900291 public static NetworkManagementService create(Context context) throws InterruptedException {
Luke Huang909b31a2019-03-16 21:21:16 +0800292 return create(context, new SystemServices());
Lorenzo Colitti7421a012013-08-20 22:51:24 +0900293 }
294
Jeff Sharkey350083e2011-06-29 10:45:16 -0700295 public void systemReady() {
Felipe Leme03e689d2016-03-02 16:17:38 -0800296 if (DBG) {
297 final long start = System.currentTimeMillis();
298 prepareNativeDaemon();
299 final long delta = System.currentTimeMillis() - start;
300 Slog.d(TAG, "Prepared in " + delta + "ms");
301 return;
302 } else {
303 prepareNativeDaemon();
304 }
Jeff Sharkey350083e2011-06-29 10:45:16 -0700305 }
306
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800307 private IBatteryStats getBatteryStats() {
308 synchronized (this) {
309 if (mBatteryStats != null) {
310 return mBatteryStats;
311 }
Lorenzo Colittia0868002017-07-11 02:29:28 +0900312 mBatteryStats =
313 IBatteryStats.Stub.asInterface(mServices.getService(BatteryStats.SERVICE_NAME));
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800314 return mBatteryStats;
315 }
316 }
317
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800318 @Override
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800319 public void registerObserver(INetworkManagementEventObserver observer) {
paulhu59148b72019-08-12 16:25:11 +0800320 NetworkStack.checkNetworkStackPermission(mContext);
Remi NGUYEN VAN9ebc3fc2019-01-29 19:12:13 +0900321 mObservers.register(observer);
San Mehat4d02d002010-01-22 16:07:46 -0800322 }
323
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800324 @Override
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800325 public void unregisterObserver(INetworkManagementEventObserver observer) {
paulhu59148b72019-08-12 16:25:11 +0800326 NetworkStack.checkNetworkStackPermission(mContext);
Remi NGUYEN VAN9ebc3fc2019-01-29 19:12:13 +0900327 mObservers.unregister(observer);
San Mehat4d02d002010-01-22 16:07:46 -0800328 }
329
Erik Klineb2cfdfb2017-01-18 20:54:14 +0900330 @FunctionalInterface
331 private interface NetworkManagementEventCallback {
332 public void sendCallback(INetworkManagementEventObserver o) throws RemoteException;
333 }
334
Remi NGUYEN VAN9ebc3fc2019-01-29 19:12:13 +0900335 private void invokeForAllObservers(NetworkManagementEventCallback eventCallback) {
336 final int length = mObservers.beginBroadcast();
337 try {
338 for (int i = 0; i < length; i++) {
339 try {
340 eventCallback.sendCallback(mObservers.getBroadcastItem(i));
341 } catch (RemoteException | RuntimeException e) {
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700342 }
Remi NGUYEN VAN9ebc3fc2019-01-29 19:12:13 +0900343 }
344 } finally {
345 mObservers.finishBroadcast();
346 }
347 }
348
349 /**
350 * Notify our observers of an interface status change
351 */
352 private void notifyInterfaceStatusChanged(String iface, boolean up) {
353 invokeForAllObservers(o -> o.interfaceStatusChanged(iface, up));
354 }
355
356 /**
357 * Notify our observers of an interface link state change
358 * (typically, an Ethernet cable has been plugged-in or unplugged).
359 */
360 private void notifyInterfaceLinkStateChanged(String iface, boolean up) {
361 invokeForAllObservers(o -> o.interfaceLinkStateChanged(iface, up));
362 }
363
364 /**
365 * Notify our observers of an interface addition.
366 */
367 private void notifyInterfaceAdded(String iface) {
368 invokeForAllObservers(o -> o.interfaceAdded(iface));
369 }
370
371 /**
372 * Notify our observers of an interface removal.
373 */
374 private void notifyInterfaceRemoved(String iface) {
375 // netd already clears out quota and alerts for removed ifaces; update
376 // our sanity-checking state.
377 mActiveAlerts.remove(iface);
378 mActiveQuotas.remove(iface);
379 invokeForAllObservers(o -> o.interfaceRemoved(iface));
380 }
381
382 /**
383 * Notify our observers of a limit reached.
384 */
385 private void notifyLimitReached(String limitName, String iface) {
386 invokeForAllObservers(o -> o.limitReached(limitName, iface));
387 }
388
389 /**
390 * Notify our observers of a change in the data activity state of the interface
391 */
392 private void notifyInterfaceClassActivity(int type, boolean isActive, long tsNanos,
393 int uid, boolean fromRadio) {
394 final boolean isMobile = ConnectivityManager.isNetworkTypeMobile(type);
395 int powerState = isActive
396 ? DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH
397 : DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
398 if (isMobile) {
399 if (!fromRadio) {
400 if (mMobileActivityFromRadio) {
401 // If this call is not coming from a report from the radio itself, but we
402 // have previously received reports from the radio, then we will take the
403 // power state to just be whatever the radio last reported.
404 powerState = mLastPowerStateFromRadio;
405 }
406 } else {
407 mMobileActivityFromRadio = true;
408 }
409 if (mLastPowerStateFromRadio != powerState) {
410 mLastPowerStateFromRadio = powerState;
411 try {
412 getBatteryStats().noteMobileRadioPowerState(powerState, tsNanos, uid);
413 } catch (RemoteException e) {
Robert Greenwalt2c9f5472014-04-21 14:50:28 -0700414 }
Muhammad Qureshi93891dd2020-01-28 10:08:24 -0800415 FrameworkStatsLog.write_non_chained(
416 FrameworkStatsLog.MOBILE_RADIO_POWER_STATE_CHANGED, uid, null, powerState);
Haoyu Baidb3c8672012-06-20 14:29:57 -0700417 }
Remi NGUYEN VAN9ebc3fc2019-01-29 19:12:13 +0900418 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700419
Remi NGUYEN VAN9ebc3fc2019-01-29 19:12:13 +0900420 if (ConnectivityManager.isNetworkTypeWifi(type)) {
421 if (mLastPowerStateFromWifi != powerState) {
422 mLastPowerStateFromWifi = powerState;
423 try {
424 getBatteryStats().noteWifiRadioPowerState(powerState, tsNanos, uid);
425 } catch (RemoteException e) {
Adam Lesinskie08af192015-03-25 16:42:59 -0700426 }
Muhammad Qureshi93891dd2020-01-28 10:08:24 -0800427 FrameworkStatsLog.write_non_chained(
428 FrameworkStatsLog.WIFI_RADIO_POWER_STATE_CHANGED, uid, null, powerState);
Adam Lesinskie08af192015-03-25 16:42:59 -0700429 }
Dianne Hackborn77b987f2014-02-26 16:20:52 -0800430 }
Lorenzo Colittid8bc8292019-01-24 13:28:50 +0900431
Remi NGUYEN VAN9ebc3fc2019-01-29 19:12:13 +0900432 if (!isMobile || fromRadio || !mMobileActivityFromRadio) {
433 // Report the change in data activity. We don't do this if this is a change
434 // on the mobile network, that is not coming from the radio itself, and we
435 // have previously seen change reports from the radio. In that case only
436 // the radio is the authority for the current state.
437 final boolean active = isActive;
438 invokeForAllObservers(o -> o.interfaceClassDataActivityChanged(
439 Integer.toString(type), active, tsNanos));
Lorenzo Colittid8bc8292019-01-24 13:28:50 +0900440 }
441
Remi NGUYEN VAN9ebc3fc2019-01-29 19:12:13 +0900442 boolean report = false;
443 synchronized (mIdleTimerLock) {
444 if (mActiveIdleTimers.isEmpty()) {
445 // If there are no idle timers, we are not monitoring activity, so we
446 // are always considered active.
447 isActive = true;
448 }
449 if (mNetworkActive != isActive) {
450 mNetworkActive = isActive;
451 report = isActive;
452 }
453 }
454 if (report) {
455 reportNetworkActive();
Dianne Hackborn77b987f2014-02-26 16:20:52 -0800456 }
Haoyu Baidb3c8672012-06-20 14:29:57 -0700457 }
458
Lorenzo Colitti07f13042017-07-10 19:06:57 +0900459 @Override
460 public void registerTetheringStatsProvider(ITetheringStatsProvider provider, String name) {
paulhu59148b72019-08-12 16:25:11 +0800461 NetworkStack.checkNetworkStackPermission(mContext);
Daulet Zhanguzinea1a7ca2020-01-03 09:46:50 +0000462 Objects.requireNonNull(provider);
Lorenzo Colitti07f13042017-07-10 19:06:57 +0900463 synchronized(mTetheringStatsProviders) {
464 mTetheringStatsProviders.put(provider, name);
465 }
466 }
467
468 @Override
469 public void unregisterTetheringStatsProvider(ITetheringStatsProvider provider) {
paulhu59148b72019-08-12 16:25:11 +0800470 NetworkStack.checkNetworkStackPermission(mContext);
Lorenzo Colitti07f13042017-07-10 19:06:57 +0900471 synchronized(mTetheringStatsProviders) {
472 mTetheringStatsProviders.remove(provider);
473 }
474 }
475
Lorenzo Colitti9f0baa92017-08-15 19:25:51 +0900476 @Override
477 public void tetherLimitReached(ITetheringStatsProvider provider) {
paulhu59148b72019-08-12 16:25:11 +0800478 NetworkStack.checkNetworkStackPermission(mContext);
Lorenzo Colitti9f0baa92017-08-15 19:25:51 +0900479 synchronized(mTetheringStatsProviders) {
480 if (!mTetheringStatsProviders.containsKey(provider)) {
481 return;
482 }
483 // No current code examines the interface parameter in a global alert. Just pass null.
Remi NGUYEN VAN9ebc3fc2019-01-29 19:12:13 +0900484 mDaemonHandler.post(() -> notifyLimitReached(LIMIT_GLOBAL_ALERT, null));
Lorenzo Colitti9f0baa92017-08-15 19:25:51 +0900485 }
486 }
487
Lorenzo Colitti9eb844e2016-03-23 23:22:49 +0900488 // Sync the state of the given chain with the native daemon.
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700489 private void syncFirewallChainLocked(int chain, String name) {
490 SparseIntArray rules;
491 synchronized (mRulesLock) {
492 final SparseIntArray uidFirewallRules = getUidFirewallRulesLR(chain);
Lorenzo Colitti9eb844e2016-03-23 23:22:49 +0900493 // Make a copy of the current rules, and then clear them. This is because
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700494 // setFirewallUidRuleInternal only pushes down rules to the native daemon if they
495 // are different from the current rules stored in the mUidFirewall*Rules array for
496 // the specified chain. If we don't clear the rules, setFirewallUidRuleInternal
497 // will do nothing.
498 rules = uidFirewallRules.clone();
Lorenzo Colitti9eb844e2016-03-23 23:22:49 +0900499 uidFirewallRules.clear();
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700500 }
501 if (rules.size() > 0) {
Lorenzo Colitti9eb844e2016-03-23 23:22:49 +0900502 // Now push the rules. setFirewallUidRuleInternal will push each of these down to the
503 // native daemon, and also add them to the mUidFirewall*Rules array for the specified
504 // chain.
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700505 if (DBG) Slog.d(TAG, "Pushing " + rules.size() + " active firewall "
506 + name + "UID rules");
Lorenzo Colitti9eb844e2016-03-23 23:22:49 +0900507 for (int i = 0; i < rules.size(); i++) {
Felipe Lemea701cad2016-05-12 09:58:14 -0700508 setFirewallUidRuleLocked(chain, rules.keyAt(i), rules.valueAt(i));
Lorenzo Colitti9eb844e2016-03-23 23:22:49 +0900509 }
510 }
511 }
512
bohu07cc3bb2016-05-03 15:58:01 -0700513 private void connectNativeNetdService() {
Lorenzo Colittia0868002017-07-11 02:29:28 +0900514 mNetdService = mServices.getNetd();
Luke Huangd290dd52018-09-04 17:08:18 +0800515 try {
Remi NGUYEN VAN9ebc3fc2019-01-29 19:12:13 +0900516 mNetdService.registerUnsolicitedEventListener(mNetdUnsolicitedEventListener);
517 if (DBG) Slog.d(TAG, "Register unsolicited event listener");
Luke Huangd290dd52018-09-04 17:08:18 +0800518 } catch (RemoteException | ServiceSpecificException e) {
Remi NGUYEN VAN9ebc3fc2019-01-29 19:12:13 +0900519 Slog.e(TAG, "Failed to set Netd unsolicited event listener " + e);
Luke Huangd290dd52018-09-04 17:08:18 +0800520 }
bohu07cc3bb2016-05-03 15:58:01 -0700521 }
522
523 /**
524 * Prepare native daemon once connected, enabling modules and pushing any
525 * existing in-memory rules.
526 */
527 private void prepareNativeDaemon() {
Lorenzo Colitti58967ba2016-02-02 17:21:21 +0900528
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700529 // push any existing quota or UID rules
530 synchronized (mQuotaLock) {
Felipe Leme65be3022016-03-22 14:53:13 -0700531
Luke Huang56a03a02018-09-07 12:02:16 +0800532 // Netd unconditionally enable bandwidth control
533 SystemProperties.set(PROP_QTAGUID_ENABLED, "1");
Lorenzo Colitti8c253ad2017-07-19 00:23:44 +0900534
Luke Huang473eb872018-07-26 17:33:14 +0800535 mStrictEnabled = true;
Lorenzo Colitti8c253ad2017-07-19 00:23:44 +0900536
Felipe Leme65be3022016-03-22 14:53:13 -0700537 setDataSaverModeEnabled(mDataSaverMode);
538
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700539 int size = mActiveQuotas.size();
540 if (size > 0) {
Felipe Leme03e689d2016-03-02 16:17:38 -0800541 if (DBG) Slog.d(TAG, "Pushing " + size + " active quota rules");
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700542 final HashMap<String, Long> activeQuotas = mActiveQuotas;
543 mActiveQuotas = Maps.newHashMap();
544 for (Map.Entry<String, Long> entry : activeQuotas.entrySet()) {
545 setInterfaceQuota(entry.getKey(), entry.getValue());
546 }
547 }
548
549 size = mActiveAlerts.size();
550 if (size > 0) {
Felipe Leme03e689d2016-03-02 16:17:38 -0800551 if (DBG) Slog.d(TAG, "Pushing " + size + " active alert rules");
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700552 final HashMap<String, Long> activeAlerts = mActiveAlerts;
553 mActiveAlerts = Maps.newHashMap();
554 for (Map.Entry<String, Long> entry : activeAlerts.entrySet()) {
555 setInterfaceAlert(entry.getKey(), entry.getValue());
556 }
557 }
558
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700559 SparseBooleanArray uidRejectOnQuota = null;
560 SparseBooleanArray uidAcceptOnQuota = null;
561 synchronized (mRulesLock) {
562 size = mUidRejectOnMetered.size();
563 if (size > 0) {
564 if (DBG) Slog.d(TAG, "Pushing " + size + " UIDs to metered blacklist rules");
565 uidRejectOnQuota = mUidRejectOnMetered;
566 mUidRejectOnMetered = new SparseBooleanArray();
567 }
568
569 size = mUidAllowOnMetered.size();
570 if (size > 0) {
571 if (DBG) Slog.d(TAG, "Pushing " + size + " UIDs to metered whitelist rules");
572 uidAcceptOnQuota = mUidAllowOnMetered;
573 mUidAllowOnMetered = new SparseBooleanArray();
574 }
575 }
576 if (uidRejectOnQuota != null) {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700577 for (int i = 0; i < uidRejectOnQuota.size(); i++) {
Felipe Leme65be3022016-03-22 14:53:13 -0700578 setUidMeteredNetworkBlacklist(uidRejectOnQuota.keyAt(i),
579 uidRejectOnQuota.valueAt(i));
580 }
581 }
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700582 if (uidAcceptOnQuota != null) {
Felipe Leme65be3022016-03-22 14:53:13 -0700583 for (int i = 0; i < uidAcceptOnQuota.size(); i++) {
584 setUidMeteredNetworkWhitelist(uidAcceptOnQuota.keyAt(i),
585 uidAcceptOnQuota.valueAt(i));
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700586 }
587 }
Jeff Sharkey605eb792014-11-04 13:34:06 -0800588
589 size = mUidCleartextPolicy.size();
590 if (size > 0) {
Felipe Leme03e689d2016-03-02 16:17:38 -0800591 if (DBG) Slog.d(TAG, "Pushing " + size + " active UID cleartext policies");
Jeff Sharkey605eb792014-11-04 13:34:06 -0800592 final SparseIntArray local = mUidCleartextPolicy;
593 mUidCleartextPolicy = new SparseIntArray();
594 for (int i = 0; i < local.size(); i++) {
595 setUidCleartextNetworkPolicy(local.keyAt(i), local.valueAt(i));
596 }
597 }
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -0700598
Robin Leec3736bc2017-03-10 16:19:54 +0000599 setFirewallEnabled(mFirewallEnabled);
Amith Yamasani15e472352015-04-24 19:06:07 -0700600
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700601 syncFirewallChainLocked(FIREWALL_CHAIN_NONE, "");
602 syncFirewallChainLocked(FIREWALL_CHAIN_STANDBY, "standby ");
603 syncFirewallChainLocked(FIREWALL_CHAIN_DOZABLE, "dozable ");
604 syncFirewallChainLocked(FIREWALL_CHAIN_POWERSAVE, "powersave ");
Xiaohui Chenb41c9f72015-06-17 15:55:37 -0700605
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700606 final int[] chains =
607 {FIREWALL_CHAIN_STANDBY, FIREWALL_CHAIN_DOZABLE, FIREWALL_CHAIN_POWERSAVE};
608 for (int chain : chains) {
609 if (getFirewallChainState(chain)) {
610 setFirewallChainEnabled(chain, true);
611 }
Felipe Leme011b98f2016-02-10 17:28:31 -0800612 }
Amith Yamasani15e472352015-04-24 19:06:07 -0700613 }
Lorenzo Colitti8c253ad2017-07-19 00:23:44 +0900614
Luke Huang56a03a02018-09-07 12:02:16 +0800615
616 try {
617 getBatteryStats().noteNetworkStatsEnabled();
618 } catch (RemoteException e) {
Lorenzo Colitti8c253ad2017-07-19 00:23:44 +0900619 }
620
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700621 }
San Mehat4d02d002010-01-22 16:07:46 -0800622
Remi NGUYEN VAN9ebc3fc2019-01-29 19:12:13 +0900623 /**
624 * Notify our observers of a new or updated interface address.
625 */
626 private void notifyAddressUpdated(String iface, LinkAddress address) {
627 invokeForAllObservers(o -> o.addressUpdated(iface, address));
628 }
629
630 /**
631 * Notify our observers of a deleted interface address.
632 */
633 private void notifyAddressRemoved(String iface, LinkAddress address) {
634 invokeForAllObservers(o -> o.addressRemoved(iface, address));
635 }
636
637 /**
638 * Notify our observers of DNS server information received.
639 */
640 private void notifyInterfaceDnsServerInfo(String iface, long lifetime, String[] addresses) {
641 invokeForAllObservers(o -> o.interfaceDnsServerInfo(iface, lifetime, addresses));
642 }
643
644 /**
645 * Notify our observers of a route change.
646 */
647 private void notifyRouteChange(boolean updated, RouteInfo route) {
648 if (updated) {
649 invokeForAllObservers(o -> o.routeUpdated(route));
650 } else {
651 invokeForAllObservers(o -> o.routeRemoved(route));
652 }
653 }
654
655 private class NetdUnsolicitedEventListener extends INetdUnsolicitedEventListener.Stub {
656 @Override
657 public void onInterfaceClassActivityChanged(boolean isActive,
658 int label, long timestamp, int uid) throws RemoteException {
659 final long timestampNanos;
660 if (timestamp <= 0) {
661 timestampNanos = SystemClock.elapsedRealtimeNanos();
662 } else {
663 timestampNanos = timestamp;
664 }
665 mDaemonHandler.post(() ->
666 notifyInterfaceClassActivity(label, isActive, timestampNanos, uid, false));
667 }
668
669 @Override
670 public void onQuotaLimitReached(String alertName, String ifName)
671 throws RemoteException {
672 mDaemonHandler.post(() -> notifyLimitReached(alertName, ifName));
673 }
674
675 @Override
676 public void onInterfaceDnsServerInfo(String ifName,
677 long lifetime, String[] servers) throws RemoteException {
678 mDaemonHandler.post(() -> notifyInterfaceDnsServerInfo(ifName, lifetime, servers));
679 }
680
681 @Override
682 public void onInterfaceAddressUpdated(String addr,
683 String ifName, int flags, int scope) throws RemoteException {
684 final LinkAddress address = new LinkAddress(addr, flags, scope);
685 mDaemonHandler.post(() -> notifyAddressUpdated(ifName, address));
686 }
687
688 @Override
689 public void onInterfaceAddressRemoved(String addr,
690 String ifName, int flags, int scope) throws RemoteException {
691 final LinkAddress address = new LinkAddress(addr, flags, scope);
692 mDaemonHandler.post(() -> notifyAddressRemoved(ifName, address));
693 }
694
695 @Override
696 public void onInterfaceAdded(String ifName) throws RemoteException {
697 mDaemonHandler.post(() -> notifyInterfaceAdded(ifName));
698 }
699
700 @Override
701 public void onInterfaceRemoved(String ifName) throws RemoteException {
702 mDaemonHandler.post(() -> notifyInterfaceRemoved(ifName));
703 }
704
705 @Override
706 public void onInterfaceChanged(String ifName, boolean up)
707 throws RemoteException {
708 mDaemonHandler.post(() -> notifyInterfaceStatusChanged(ifName, up));
709 }
710
711 @Override
712 public void onInterfaceLinkStateChanged(String ifName, boolean up)
713 throws RemoteException {
714 mDaemonHandler.post(() -> notifyInterfaceLinkStateChanged(ifName, up));
715 }
716
717 @Override
718 public void onRouteChanged(boolean updated,
719 String route, String gateway, String ifName) throws RemoteException {
720 final RouteInfo processRoute = new RouteInfo(new IpPrefix(route),
721 ("".equals(gateway)) ? null : InetAddresses.parseNumericAddress(gateway),
722 ifName);
723 mDaemonHandler.post(() -> notifyRouteChange(updated, processRoute));
724 }
725
726 @Override
727 public void onStrictCleartextDetected(int uid, String hex) throws RemoteException {
728 // Don't need to post to mDaemonHandler because the only thing
729 // that notifyCleartextNetwork does is post to a handler
730 ActivityManager.getService().notifyCleartextNetwork(uid,
731 HexDump.hexStringToByteArray(hex));
732 }
Remi NGUYEN VANeec0ed42019-04-09 14:01:51 +0900733
734 @Override
735 public int getInterfaceVersion() {
736 return INetdUnsolicitedEventListener.VERSION;
737 }
Paul Trautrimaf2e0822020-01-23 14:55:57 +0900738
739 @Override
740 public String getInterfaceHash() {
741 return INetdUnsolicitedEventListener.HASH;
742 }
Remi NGUYEN VAN9ebc3fc2019-01-29 19:12:13 +0900743 }
744
San Mehat873f2142010-01-14 10:25:07 -0800745 //
San Mehat873f2142010-01-14 10:25:07 -0800746 // INetworkManagementService members
747 //
Erik Kline4e37b702016-07-05 11:34:21 +0900748 @Override
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800749 public String[] listInterfaces() {
paulhu79ebe4f2019-12-06 16:45:38 +0800750 // TODO: Remove CONNECTIVITY_INTERNAL after bluetooth tethering has no longer called these
751 // APIs.
752 NetworkStack.checkNetworkStackPermissionOr(mContext, CONNECTIVITY_INTERNAL);
Kenny Roota80ce062010-06-01 13:23:53 -0700753 try {
Luke Huang1b4f92f2018-12-12 15:59:31 +0800754 return mNetdService.interfaceGetList();
Luke Huang14f75442018-08-15 19:22:54 +0800755 } catch (RemoteException | ServiceSpecificException e) {
756 throw new IllegalStateException(e);
Kenny Roota80ce062010-06-01 13:23:53 -0700757 }
San Mehated4fc8a2010-01-22 12:28:36 -0800758 }
759
Lorenzo Colitticc7f1db2019-03-18 23:50:34 +0900760 /**
761 * Convert InterfaceConfiguration to InterfaceConfigurationParcel with given ifname.
762 */
763 private static InterfaceConfigurationParcel toStableParcel(InterfaceConfiguration cfg,
764 String iface) {
765 InterfaceConfigurationParcel cfgParcel = new InterfaceConfigurationParcel();
766 cfgParcel.ifName = iface;
767 String hwAddr = cfg.getHardwareAddress();
768 if (!TextUtils.isEmpty(hwAddr)) {
769 cfgParcel.hwAddr = hwAddr;
770 } else {
771 cfgParcel.hwAddr = "";
772 }
773 cfgParcel.ipv4Addr = cfg.getLinkAddress().getAddress().getHostAddress();
774 cfgParcel.prefixLength = cfg.getLinkAddress().getPrefixLength();
775 ArrayList<String> flags = new ArrayList<>();
776 for (String flag : cfg.getFlags()) {
777 flags.add(flag);
778 }
779 cfgParcel.flags = flags.toArray(new String[0]);
780
781 return cfgParcel;
782 }
783
784 /**
785 * Construct InterfaceConfiguration from InterfaceConfigurationParcel.
786 */
787 public static InterfaceConfiguration fromStableParcel(InterfaceConfigurationParcel p) {
788 InterfaceConfiguration cfg = new InterfaceConfiguration();
789 cfg.setHardwareAddress(p.hwAddr);
790
791 final InetAddress addr = NetworkUtils.numericToInetAddress(p.ipv4Addr);
792 cfg.setLinkAddress(new LinkAddress(addr, p.prefixLength));
793 for (String flag : p.flags) {
794 cfg.setFlag(flag);
795 }
796
797 return cfg;
798 }
799
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800800 @Override
801 public InterfaceConfiguration getInterfaceConfig(String iface) {
paulhu79ebe4f2019-12-06 16:45:38 +0800802 // TODO: Remove CONNECTIVITY_INTERNAL after bluetooth tethering has no longer called these
803 // APIs.
804 NetworkStack.checkNetworkStackPermissionOr(mContext, CONNECTIVITY_INTERNAL);
Luke Huang14f75442018-08-15 19:22:54 +0800805 final InterfaceConfigurationParcel result;
Kenny Roota80ce062010-06-01 13:23:53 -0700806 try {
Luke Huang14f75442018-08-15 19:22:54 +0800807 result = mNetdService.interfaceGetCfg(iface);
808 } catch (RemoteException | ServiceSpecificException e) {
809 throw new IllegalStateException(e);
Kenny Roota80ce062010-06-01 13:23:53 -0700810 }
San Mehated4fc8a2010-01-22 12:28:36 -0800811
San Mehated4fc8a2010-01-22 12:28:36 -0800812 try {
Lorenzo Colitticc7f1db2019-03-18 23:50:34 +0900813 final InterfaceConfiguration cfg = fromStableParcel(result);
Luke Huang14f75442018-08-15 19:22:54 +0800814 return cfg;
815 } catch (IllegalArgumentException iae) {
816 throw new IllegalStateException("Invalid InterfaceConfigurationParcel", iae);
San Mehated4fc8a2010-01-22 12:28:36 -0800817 }
San Mehated4fc8a2010-01-22 12:28:36 -0800818 }
819
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800820 @Override
821 public void setInterfaceConfig(String iface, InterfaceConfiguration cfg) {
paulhu79ebe4f2019-12-06 16:45:38 +0800822 // TODO: Remove CONNECTIVITY_INTERNAL after bluetooth tethering has no longer called these
823 // APIs.
824 NetworkStack.checkNetworkStackPermissionOr(mContext, CONNECTIVITY_INTERNAL);
Jeff Sharkeyddba1062011-11-29 18:37:04 -0800825 LinkAddress linkAddr = cfg.getLinkAddress();
Robert Greenwalt2d2afd12011-02-01 15:30:46 -0800826 if (linkAddr == null || linkAddr.getAddress() == null) {
827 throw new IllegalStateException("Null LinkAddress given");
Robert Greenwalted126402011-01-28 15:34:55 -0800828 }
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800829
Lorenzo Colitticc7f1db2019-03-18 23:50:34 +0900830 final InterfaceConfigurationParcel cfgParcel = toStableParcel(cfg, iface);
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800831
Kenny Roota80ce062010-06-01 13:23:53 -0700832 try {
Luke Huang14f75442018-08-15 19:22:54 +0800833 mNetdService.interfaceSetCfg(cfgParcel);
834 } catch (RemoteException | ServiceSpecificException e) {
835 throw new IllegalStateException(e);
Kenny Roota80ce062010-06-01 13:23:53 -0700836 }
San Mehat873f2142010-01-14 10:25:07 -0800837 }
838
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800839 @Override
840 public void setInterfaceDown(String iface) {
paulhu59148b72019-08-12 16:25:11 +0800841 NetworkStack.checkNetworkStackPermission(mContext);
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800842 final InterfaceConfiguration ifcg = getInterfaceConfig(iface);
Jeff Sharkeyddba1062011-11-29 18:37:04 -0800843 ifcg.setInterfaceDown();
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800844 setInterfaceConfig(iface, ifcg);
Irfan Sheriff7244c972011-08-05 20:40:45 -0700845 }
846
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800847 @Override
848 public void setInterfaceUp(String iface) {
paulhu59148b72019-08-12 16:25:11 +0800849 NetworkStack.checkNetworkStackPermission(mContext);
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800850 final InterfaceConfiguration ifcg = getInterfaceConfig(iface);
Jeff Sharkeyddba1062011-11-29 18:37:04 -0800851 ifcg.setInterfaceUp();
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800852 setInterfaceConfig(iface, ifcg);
Irfan Sheriff7244c972011-08-05 20:40:45 -0700853 }
854
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800855 @Override
856 public void setInterfaceIpv6PrivacyExtensions(String iface, boolean enable) {
paulhu59148b72019-08-12 16:25:11 +0800857 NetworkStack.checkNetworkStackPermission(mContext);
Irfan Sheriff73293612011-09-14 12:31:56 -0700858 try {
Luke Huang14f75442018-08-15 19:22:54 +0800859 mNetdService.interfaceSetIPv6PrivacyExtensions(iface, enable);
860 } catch (RemoteException | ServiceSpecificException e) {
861 throw new IllegalStateException(e);
Irfan Sheriff73293612011-09-14 12:31:56 -0700862 }
863 }
864
Irfan Sherifff5600612011-06-16 10:26:28 -0700865 /* TODO: This is right now a IPv4 only function. Works for wifi which loses its
866 IPv6 addresses on interface down, but we need to do full clean up here */
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800867 @Override
868 public void clearInterfaceAddresses(String iface) {
paulhu59148b72019-08-12 16:25:11 +0800869 NetworkStack.checkNetworkStackPermission(mContext);
Irfan Sherifff5600612011-06-16 10:26:28 -0700870 try {
Luke Huang14f75442018-08-15 19:22:54 +0800871 mNetdService.interfaceClearAddrs(iface);
872 } catch (RemoteException | ServiceSpecificException e) {
873 throw new IllegalStateException(e);
Irfan Sherifff5600612011-06-16 10:26:28 -0700874 }
875 }
876
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800877 @Override
878 public void enableIpv6(String iface) {
paulhu59148b72019-08-12 16:25:11 +0800879 NetworkStack.checkNetworkStackPermission(mContext);
repo sync7960d9f2011-09-29 12:40:02 -0700880 try {
Luke Huang14f75442018-08-15 19:22:54 +0800881 mNetdService.interfaceSetEnableIPv6(iface, true);
882 } catch (RemoteException | ServiceSpecificException e) {
883 throw new IllegalStateException(e);
repo sync7960d9f2011-09-29 12:40:02 -0700884 }
885 }
886
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800887 @Override
Joel Scherpelz2db10742017-06-07 15:38:38 +0900888 public void setIPv6AddrGenMode(String iface, int mode) throws ServiceSpecificException {
889 try {
890 mNetdService.setIPv6AddrGenMode(iface, mode);
891 } catch (RemoteException e) {
892 throw e.rethrowAsRuntimeException();
893 }
894 }
895
896 @Override
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800897 public void disableIpv6(String iface) {
paulhu59148b72019-08-12 16:25:11 +0800898 NetworkStack.checkNetworkStackPermission(mContext);
repo sync7960d9f2011-09-29 12:40:02 -0700899 try {
Luke Huang14f75442018-08-15 19:22:54 +0800900 mNetdService.interfaceSetEnableIPv6(iface, false);
901 } catch (RemoteException | ServiceSpecificException e) {
902 throw new IllegalStateException(e);
repo sync7960d9f2011-09-29 12:40:02 -0700903 }
904 }
905
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800906 @Override
Sreeram Ramachandranb2829fa2014-04-15 19:07:12 -0700907 public void addRoute(int netId, RouteInfo route) {
markchiena9d9ef82020-01-07 14:43:17 +0800908 NetworkStack.checkNetworkStackPermission(mContext);
909 RouteUtils.modifyRoute(mNetdService, ModifyOperation.ADD, netId, route);
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700910 }
911
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800912 @Override
Sreeram Ramachandranb2829fa2014-04-15 19:07:12 -0700913 public void removeRoute(int netId, RouteInfo route) {
paulhu59148b72019-08-12 16:25:11 +0800914 NetworkStack.checkNetworkStackPermission(mContext);
markchiena9d9ef82020-01-07 14:43:17 +0800915 RouteUtils.modifyRoute(mNetdService, ModifyOperation.REMOVE, netId, route);
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700916 }
917
918 private ArrayList<String> readRouteList(String filename) {
919 FileInputStream fstream = null;
Christopher Wiley212b95f2016-08-02 11:38:57 -0700920 ArrayList<String> list = new ArrayList<>();
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700921
922 try {
923 fstream = new FileInputStream(filename);
924 DataInputStream in = new DataInputStream(fstream);
925 BufferedReader br = new BufferedReader(new InputStreamReader(in));
926 String s;
927
928 // throw away the title line
929
930 while (((s = br.readLine()) != null) && (s.length() != 0)) {
931 list.add(s);
932 }
933 } catch (IOException ex) {
934 // return current list, possibly empty
935 } finally {
936 if (fstream != null) {
937 try {
938 fstream.close();
939 } catch (IOException ex) {}
940 }
941 }
942
943 return list;
944 }
945
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800946 @Override
sy.yun9d9b74a2013-09-02 05:24:09 +0900947 public void setMtu(String iface, int mtu) {
paulhu59148b72019-08-12 16:25:11 +0800948 NetworkStack.checkNetworkStackPermission(mContext);
sy.yun9d9b74a2013-09-02 05:24:09 +0900949
sy.yun9d9b74a2013-09-02 05:24:09 +0900950 try {
Luke Huang14f75442018-08-15 19:22:54 +0800951 mNetdService.interfaceSetMtu(iface, mtu);
952 } catch (RemoteException | ServiceSpecificException e) {
953 throw new IllegalStateException(e);
sy.yun9d9b74a2013-09-02 05:24:09 +0900954 }
955 }
956
957 @Override
San Mehat873f2142010-01-14 10:25:07 -0800958 public void shutdown() {
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800959 // TODO: remove from aidl if nobody calls externally
960 mContext.enforceCallingOrSelfPermission(SHUTDOWN, TAG);
San Mehat873f2142010-01-14 10:25:07 -0800961
Felipe Leme03e689d2016-03-02 16:17:38 -0800962 Slog.i(TAG, "Shutting down");
San Mehat873f2142010-01-14 10:25:07 -0800963 }
964
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800965 @Override
San Mehat873f2142010-01-14 10:25:07 -0800966 public boolean getIpForwardingEnabled() throws IllegalStateException{
paulhu59148b72019-08-12 16:25:11 +0800967 NetworkStack.checkNetworkStackPermission(mContext);
San Mehat873f2142010-01-14 10:25:07 -0800968
Kenny Roota80ce062010-06-01 13:23:53 -0700969 try {
Luke Huang4db488b2018-08-16 15:37:31 +0800970 final boolean isEnabled = mNetdService.ipfwdEnabled();
971 return isEnabled;
972 } catch (RemoteException | ServiceSpecificException e) {
973 throw new IllegalStateException(e);
Kenny Roota80ce062010-06-01 13:23:53 -0700974 }
San Mehat873f2142010-01-14 10:25:07 -0800975 }
976
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800977 @Override
978 public void setIpForwardingEnabled(boolean enable) {
paulhu59148b72019-08-12 16:25:11 +0800979 NetworkStack.checkNetworkStackPermission(mContext);
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800980 try {
Luke Huang4db488b2018-08-16 15:37:31 +0800981 if (enable) {
982 mNetdService.ipfwdEnableForwarding("tethering");
983 } else {
984 mNetdService.ipfwdDisableForwarding("tethering");
985 }
986 } catch (RemoteException | ServiceSpecificException e) {
987 throw new IllegalStateException(e);
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800988 }
San Mehat873f2142010-01-14 10:25:07 -0800989 }
990
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800991 @Override
992 public void startTethering(String[] dhcpRange) {
Luke Huangb0d52462019-03-21 14:43:08 +0800993 startTetheringWithConfiguration(true, dhcpRange);
994 }
995
996 @Override
997 public void startTetheringWithConfiguration(boolean usingLegacyDnsProxy, String[] dhcpRange) {
paulhu59148b72019-08-12 16:25:11 +0800998 NetworkStack.checkNetworkStackPermission(mContext);
Kenny Roota80ce062010-06-01 13:23:53 -0700999 try {
markchiena9d9ef82020-01-07 14:43:17 +08001000 NetdUtils.tetherStart(mNetdService, usingLegacyDnsProxy, dhcpRange);
Luke Huang4a32bf42018-08-21 19:09:45 +08001001 } catch (RemoteException | ServiceSpecificException e) {
1002 throw new IllegalStateException(e);
Kenny Roota80ce062010-06-01 13:23:53 -07001003 }
San Mehat873f2142010-01-14 10:25:07 -08001004 }
1005
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001006 @Override
1007 public void stopTethering() {
paulhu59148b72019-08-12 16:25:11 +08001008 NetworkStack.checkNetworkStackPermission(mContext);
Kenny Roota80ce062010-06-01 13:23:53 -07001009 try {
Luke Huang4a32bf42018-08-21 19:09:45 +08001010 mNetdService.tetherStop();
1011 } catch (RemoteException | ServiceSpecificException e) {
1012 throw new IllegalStateException(e);
Kenny Roota80ce062010-06-01 13:23:53 -07001013 }
San Mehat873f2142010-01-14 10:25:07 -08001014 }
1015
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001016 @Override
1017 public boolean isTetheringStarted() {
paulhu59148b72019-08-12 16:25:11 +08001018 NetworkStack.checkNetworkStackPermission(mContext);
San Mehat873f2142010-01-14 10:25:07 -08001019
Kenny Roota80ce062010-06-01 13:23:53 -07001020 try {
Luke Huang4a32bf42018-08-21 19:09:45 +08001021 final boolean isEnabled = mNetdService.tetherIsEnabled();
1022 return isEnabled;
1023 } catch (RemoteException | ServiceSpecificException e) {
1024 throw new IllegalStateException(e);
Kenny Roota80ce062010-06-01 13:23:53 -07001025 }
San Mehat873f2142010-01-14 10:25:07 -08001026 }
Matthew Xiefe19f122012-07-12 16:03:32 -07001027
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001028 @Override
1029 public void tetherInterface(String iface) {
paulhu59148b72019-08-12 16:25:11 +08001030 NetworkStack.checkNetworkStackPermission(mContext);
Kenny Roota80ce062010-06-01 13:23:53 -07001031 try {
markchiena9d9ef82020-01-07 14:43:17 +08001032 final LinkAddress addr = getInterfaceConfig(iface).getLinkAddress();
1033 final IpPrefix dest = new IpPrefix(addr.getAddress(), addr.getPrefixLength());
1034 NetdUtils.tetherInterface(mNetdService, iface, dest);
Luke Huang4a32bf42018-08-21 19:09:45 +08001035 } catch (RemoteException | ServiceSpecificException e) {
1036 throw new IllegalStateException(e);
Kenny Roota80ce062010-06-01 13:23:53 -07001037 }
San Mehat873f2142010-01-14 10:25:07 -08001038 }
1039
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001040 @Override
San Mehat873f2142010-01-14 10:25:07 -08001041 public void untetherInterface(String iface) {
paulhu59148b72019-08-12 16:25:11 +08001042 NetworkStack.checkNetworkStackPermission(mContext);
Kenny Roota80ce062010-06-01 13:23:53 -07001043 try {
markchiena9d9ef82020-01-07 14:43:17 +08001044 NetdUtils.untetherInterface(mNetdService, iface);
Luke Huang4a32bf42018-08-21 19:09:45 +08001045 } catch (RemoteException | ServiceSpecificException e) {
1046 throw new IllegalStateException(e);
Kenny Roota80ce062010-06-01 13:23:53 -07001047 }
San Mehat873f2142010-01-14 10:25:07 -08001048 }
1049
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001050 @Override
1051 public String[] listTetheredInterfaces() {
paulhu59148b72019-08-12 16:25:11 +08001052 NetworkStack.checkNetworkStackPermission(mContext);
Kenny Roota80ce062010-06-01 13:23:53 -07001053 try {
Luke Huang1b4f92f2018-12-12 15:59:31 +08001054 return mNetdService.tetherInterfaceList();
Luke Huang4a32bf42018-08-21 19:09:45 +08001055 } catch (RemoteException | ServiceSpecificException e) {
1056 throw new IllegalStateException(e);
Kenny Roota80ce062010-06-01 13:23:53 -07001057 }
San Mehat873f2142010-01-14 10:25:07 -08001058 }
1059
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001060 @Override
Lorenzo Colittib57edc52014-08-22 17:10:50 -07001061 public void setDnsForwarders(Network network, String[] dns) {
paulhu59148b72019-08-12 16:25:11 +08001062 NetworkStack.checkNetworkStackPermission(mContext);
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001063
Lorenzo Colittib57edc52014-08-22 17:10:50 -07001064 int netId = (network != null) ? network.netId : ConnectivityManager.NETID_UNSET;
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001065
San Mehat873f2142010-01-14 10:25:07 -08001066 try {
Luke Huang4a32bf42018-08-21 19:09:45 +08001067 mNetdService.tetherDnsSet(netId, dns);
1068 } catch (RemoteException | ServiceSpecificException e) {
1069 throw new IllegalStateException(e);
San Mehat873f2142010-01-14 10:25:07 -08001070 }
1071 }
1072
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001073 @Override
1074 public String[] getDnsForwarders() {
paulhu59148b72019-08-12 16:25:11 +08001075 NetworkStack.checkNetworkStackPermission(mContext);
Kenny Roota80ce062010-06-01 13:23:53 -07001076 try {
Luke Huang1b4f92f2018-12-12 15:59:31 +08001077 return mNetdService.tetherDnsList();
Luke Huang4a32bf42018-08-21 19:09:45 +08001078 } catch (RemoteException | ServiceSpecificException e) {
1079 throw new IllegalStateException(e);
Kenny Roota80ce062010-06-01 13:23:53 -07001080 }
San Mehat873f2142010-01-14 10:25:07 -08001081 }
1082
jiaguo1da35f72014-01-09 16:39:59 +08001083 private List<InterfaceAddress> excludeLinkLocal(List<InterfaceAddress> addresses) {
Christopher Wiley212b95f2016-08-02 11:38:57 -07001084 ArrayList<InterfaceAddress> filtered = new ArrayList<>(addresses.size());
jiaguo1da35f72014-01-09 16:39:59 +08001085 for (InterfaceAddress ia : addresses) {
1086 if (!ia.getAddress().isLinkLocalAddress())
1087 filtered.add(ia);
1088 }
1089 return filtered;
1090 }
1091
Lorenzo Colitti35e36db2015-02-26 01:25:36 +09001092 private void modifyInterfaceForward(boolean add, String fromIface, String toIface) {
Lorenzo Colitti35e36db2015-02-26 01:25:36 +09001093 try {
Luke Huang4db488b2018-08-16 15:37:31 +08001094 if (add) {
1095 mNetdService.ipfwdAddInterfaceForward(fromIface, toIface);
1096 } else {
1097 mNetdService.ipfwdRemoveInterfaceForward(fromIface, toIface);
1098 }
1099 } catch (RemoteException | ServiceSpecificException e) {
1100 throw new IllegalStateException(e);
Lorenzo Colitti35e36db2015-02-26 01:25:36 +09001101 }
1102 }
1103
1104 @Override
1105 public void startInterfaceForwarding(String fromIface, String toIface) {
paulhu59148b72019-08-12 16:25:11 +08001106 NetworkStack.checkNetworkStackPermission(mContext);
Lorenzo Colitti35e36db2015-02-26 01:25:36 +09001107 modifyInterfaceForward(true, fromIface, toIface);
1108 }
1109
1110 @Override
1111 public void stopInterfaceForwarding(String fromIface, String toIface) {
paulhu59148b72019-08-12 16:25:11 +08001112 NetworkStack.checkNetworkStackPermission(mContext);
Lorenzo Colitti35e36db2015-02-26 01:25:36 +09001113 modifyInterfaceForward(false, fromIface, toIface);
1114 }
1115
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001116 @Override
1117 public void enableNat(String internalInterface, String externalInterface) {
paulhu59148b72019-08-12 16:25:11 +08001118 NetworkStack.checkNetworkStackPermission(mContext);
Kenny Roota80ce062010-06-01 13:23:53 -07001119 try {
Luke Huanga31e0732018-10-22 13:23:10 +09001120 mNetdService.tetherAddForward(internalInterface, externalInterface);
1121 } catch (RemoteException | ServiceSpecificException e) {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001122 throw new IllegalStateException(e);
Kenny Roota80ce062010-06-01 13:23:53 -07001123 }
San Mehat873f2142010-01-14 10:25:07 -08001124 }
1125
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001126 @Override
1127 public void disableNat(String internalInterface, String externalInterface) {
paulhu59148b72019-08-12 16:25:11 +08001128 NetworkStack.checkNetworkStackPermission(mContext);
Kenny Roota80ce062010-06-01 13:23:53 -07001129 try {
Luke Huanga31e0732018-10-22 13:23:10 +09001130 mNetdService.tetherRemoveForward(internalInterface, externalInterface);
1131 } catch (RemoteException | ServiceSpecificException e) {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001132 throw new IllegalStateException(e);
Kenny Roota80ce062010-06-01 13:23:53 -07001133 }
San Mehat873f2142010-01-14 10:25:07 -08001134 }
San Mehat72759df2010-01-19 13:50:37 -08001135
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001136 @Override
Dianne Hackborn77b987f2014-02-26 16:20:52 -08001137 public void addIdleTimer(String iface, int timeout, final int type) {
paulhu59148b72019-08-12 16:25:11 +08001138 NetworkStack.checkNetworkStackPermission(mContext);
Haoyu Bai04124232012-06-28 15:26:19 -07001139
1140 if (DBG) Slog.d(TAG, "Adding idletimer");
1141
1142 synchronized (mIdleTimerLock) {
1143 IdleTimerParams params = mActiveIdleTimers.get(iface);
1144 if (params != null) {
1145 // the interface already has idletimer, update network count
1146 params.networkCount++;
1147 return;
1148 }
1149
1150 try {
Luke Huanga62d0492018-07-27 20:08:21 +08001151 mNetdService.idletimerAddInterface(iface, timeout, Integer.toString(type));
1152 } catch (RemoteException | ServiceSpecificException e) {
1153 throw new IllegalStateException(e);
Haoyu Bai04124232012-06-28 15:26:19 -07001154 }
Dianne Hackborn77b987f2014-02-26 16:20:52 -08001155 mActiveIdleTimers.put(iface, new IdleTimerParams(timeout, type));
1156
Dianne Hackborne13c4c02014-02-11 17:18:35 -08001157 // Networks start up.
Dianne Hackborn77b987f2014-02-26 16:20:52 -08001158 if (ConnectivityManager.isNetworkTypeMobile(type)) {
1159 mNetworkActive = false;
1160 }
Remi NGUYEN VAN9ebc3fc2019-01-29 19:12:13 +09001161 mDaemonHandler.post(() -> notifyInterfaceClassActivity(type, true,
1162 SystemClock.elapsedRealtimeNanos(), -1, false));
Haoyu Bai04124232012-06-28 15:26:19 -07001163 }
1164 }
1165
1166 @Override
1167 public void removeIdleTimer(String iface) {
paulhu59148b72019-08-12 16:25:11 +08001168 NetworkStack.checkNetworkStackPermission(mContext);
Haoyu Bai04124232012-06-28 15:26:19 -07001169
1170 if (DBG) Slog.d(TAG, "Removing idletimer");
1171
1172 synchronized (mIdleTimerLock) {
Dianne Hackborn77b987f2014-02-26 16:20:52 -08001173 final IdleTimerParams params = mActiveIdleTimers.get(iface);
Haoyu Bai04124232012-06-28 15:26:19 -07001174 if (params == null || --(params.networkCount) > 0) {
1175 return;
1176 }
1177
1178 try {
Luke Huanga62d0492018-07-27 20:08:21 +08001179 mNetdService.idletimerRemoveInterface(iface,
1180 params.timeout, Integer.toString(params.type));
1181 } catch (RemoteException | ServiceSpecificException e) {
1182 throw new IllegalStateException(e);
Haoyu Bai04124232012-06-28 15:26:19 -07001183 }
1184 mActiveIdleTimers.remove(iface);
Remi NGUYEN VAN9ebc3fc2019-01-29 19:12:13 +09001185 mDaemonHandler.post(() -> notifyInterfaceClassActivity(params.type, false,
1186 SystemClock.elapsedRealtimeNanos(), -1, false));
Haoyu Bai04124232012-06-28 15:26:19 -07001187 }
1188 }
1189
1190 @Override
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001191 public void setInterfaceQuota(String iface, long quotaBytes) {
paulhu59148b72019-08-12 16:25:11 +08001192 NetworkStack.checkNetworkStackPermission(mContext);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001193
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001194 synchronized (mQuotaLock) {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001195 if (mActiveQuotas.containsKey(iface)) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001196 throw new IllegalStateException("iface " + iface + " already has quota");
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001197 }
1198
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001199 try {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001200 // TODO: support quota shared across interfaces
Luke Huangc7bea8662018-08-07 16:04:26 +08001201 mNetdService.bandwidthSetInterfaceQuota(iface, quotaBytes);
1202
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001203 mActiveQuotas.put(iface, quotaBytes);
Luke Huangc7bea8662018-08-07 16:04:26 +08001204 } catch (RemoteException | ServiceSpecificException e) {
1205 throw new IllegalStateException(e);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001206 }
Lorenzo Colitti50b60fc2017-08-11 13:47:49 +09001207
1208 synchronized (mTetheringStatsProviders) {
1209 for (ITetheringStatsProvider provider : mTetheringStatsProviders.keySet()) {
1210 try {
1211 provider.setInterfaceQuota(iface, quotaBytes);
1212 } catch (RemoteException e) {
1213 Log.e(TAG, "Problem setting tethering data limit on provider " +
1214 mTetheringStatsProviders.get(provider) + ": " + e);
1215 }
1216 }
1217 }
Ashish Sharma50fd36d2011-06-15 19:34:53 -07001218 }
1219 }
1220
1221 @Override
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001222 public void removeInterfaceQuota(String iface) {
paulhu59148b72019-08-12 16:25:11 +08001223 NetworkStack.checkNetworkStackPermission(mContext);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001224
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001225 synchronized (mQuotaLock) {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001226 if (!mActiveQuotas.containsKey(iface)) {
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001227 // TODO: eventually consider throwing
1228 return;
1229 }
1230
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001231 mActiveQuotas.remove(iface);
1232 mActiveAlerts.remove(iface);
Jeff Sharkey38ddeaa2011-11-08 13:04:22 -08001233
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001234 try {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001235 // TODO: support quota shared across interfaces
Luke Huangc7bea8662018-08-07 16:04:26 +08001236 mNetdService.bandwidthRemoveInterfaceQuota(iface);
1237 } catch (RemoteException | ServiceSpecificException e) {
1238 throw new IllegalStateException(e);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001239 }
Lorenzo Colitti50b60fc2017-08-11 13:47:49 +09001240
1241 synchronized (mTetheringStatsProviders) {
1242 for (ITetheringStatsProvider provider : mTetheringStatsProviders.keySet()) {
1243 try {
1244 provider.setInterfaceQuota(iface, ITetheringStatsProvider.QUOTA_UNLIMITED);
1245 } catch (RemoteException e) {
1246 Log.e(TAG, "Problem removing tethering data limit on provider " +
1247 mTetheringStatsProviders.get(provider) + ": " + e);
1248 }
1249 }
1250 }
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001251 }
1252 }
1253
1254 @Override
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001255 public void setInterfaceAlert(String iface, long alertBytes) {
paulhu59148b72019-08-12 16:25:11 +08001256 NetworkStack.checkNetworkStackPermission(mContext);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001257
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001258 // quick sanity check
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001259 if (!mActiveQuotas.containsKey(iface)) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001260 throw new IllegalStateException("setting alert requires existing quota on iface");
1261 }
1262
1263 synchronized (mQuotaLock) {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001264 if (mActiveAlerts.containsKey(iface)) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001265 throw new IllegalStateException("iface " + iface + " already has alert");
1266 }
1267
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001268 try {
1269 // TODO: support alert shared across interfaces
Luke Huangc7bea8662018-08-07 16:04:26 +08001270 mNetdService.bandwidthSetInterfaceAlert(iface, alertBytes);
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001271 mActiveAlerts.put(iface, alertBytes);
Luke Huangc7bea8662018-08-07 16:04:26 +08001272 } catch (RemoteException | ServiceSpecificException e) {
1273 throw new IllegalStateException(e);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001274 }
1275 }
1276 }
1277
1278 @Override
1279 public void removeInterfaceAlert(String iface) {
paulhu59148b72019-08-12 16:25:11 +08001280 NetworkStack.checkNetworkStackPermission(mContext);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001281
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001282 synchronized (mQuotaLock) {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001283 if (!mActiveAlerts.containsKey(iface)) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001284 // TODO: eventually consider throwing
1285 return;
1286 }
1287
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001288 try {
1289 // TODO: support alert shared across interfaces
Luke Huangc7bea8662018-08-07 16:04:26 +08001290 mNetdService.bandwidthRemoveInterfaceAlert(iface);
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001291 mActiveAlerts.remove(iface);
Luke Huangc7bea8662018-08-07 16:04:26 +08001292 } catch (RemoteException | ServiceSpecificException e) {
1293 throw new IllegalStateException(e);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001294 }
1295 }
1296 }
1297
1298 @Override
1299 public void setGlobalAlert(long alertBytes) {
paulhu59148b72019-08-12 16:25:11 +08001300 NetworkStack.checkNetworkStackPermission(mContext);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001301
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001302 try {
Luke Huangc7bea8662018-08-07 16:04:26 +08001303 mNetdService.bandwidthSetGlobalAlert(alertBytes);
1304 } catch (RemoteException | ServiceSpecificException e) {
1305 throw new IllegalStateException(e);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001306 }
1307 }
1308
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001309 private void setUidOnMeteredNetworkList(int uid, boolean blacklist, boolean enable) {
paulhu59148b72019-08-12 16:25:11 +08001310 NetworkStack.checkNetworkStackPermission(mContext);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001311
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001312 synchronized (mQuotaLock) {
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001313 boolean oldEnable;
1314 SparseBooleanArray quotaList;
1315 synchronized (mRulesLock) {
1316 quotaList = blacklist ? mUidRejectOnMetered : mUidAllowOnMetered;
1317 oldEnable = quotaList.get(uid, false);
1318 }
Felipe Leme65be3022016-03-22 14:53:13 -07001319 if (oldEnable == enable) {
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001320 // TODO: eventually consider throwing
1321 return;
1322 }
1323
Felipe Leme29e72ea2016-09-08 13:26:55 -07001324 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "inetd bandwidth");
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001325 try {
Luke Huangc7bea8662018-08-07 16:04:26 +08001326 if (blacklist) {
1327 if (enable) {
1328 mNetdService.bandwidthAddNaughtyApp(uid);
1329 } else {
1330 mNetdService.bandwidthRemoveNaughtyApp(uid);
1331 }
1332 } else {
1333 if (enable) {
1334 mNetdService.bandwidthAddNiceApp(uid);
1335 } else {
1336 mNetdService.bandwidthRemoveNiceApp(uid);
1337 }
1338 }
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001339 synchronized (mRulesLock) {
1340 if (enable) {
1341 quotaList.put(uid, true);
1342 } else {
1343 quotaList.delete(uid);
1344 }
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001345 }
Luke Huangc7bea8662018-08-07 16:04:26 +08001346 } catch (RemoteException | ServiceSpecificException e) {
1347 throw new IllegalStateException(e);
Felipe Leme29e72ea2016-09-08 13:26:55 -07001348 } finally {
1349 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001350 }
Ashish Sharma50fd36d2011-06-15 19:34:53 -07001351 }
1352 }
1353
Jeff Sharkey63d27a92011-08-03 17:04:22 -07001354 @Override
Felipe Leme65be3022016-03-22 14:53:13 -07001355 public void setUidMeteredNetworkBlacklist(int uid, boolean enable) {
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001356 setUidOnMeteredNetworkList(uid, true, enable);
Felipe Leme65be3022016-03-22 14:53:13 -07001357 }
1358
1359 @Override
1360 public void setUidMeteredNetworkWhitelist(int uid, boolean enable) {
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001361 setUidOnMeteredNetworkList(uid, false, enable);
Felipe Leme65be3022016-03-22 14:53:13 -07001362 }
1363
1364 @Override
1365 public boolean setDataSaverModeEnabled(boolean enable) {
Sehee Parka9139bc2017-12-22 13:54:05 +09001366 mContext.enforceCallingOrSelfPermission(NETWORK_SETTINGS, TAG);
1367
Felipe Leme65be3022016-03-22 14:53:13 -07001368 if (DBG) Log.d(TAG, "setDataSaverMode: " + enable);
1369 synchronized (mQuotaLock) {
1370 if (mDataSaverMode == enable) {
1371 Log.w(TAG, "setDataSaverMode(): already " + mDataSaverMode);
1372 return true;
1373 }
Felipe Leme29e72ea2016-09-08 13:26:55 -07001374 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "bandwidthEnableDataSaver");
Felipe Leme65be3022016-03-22 14:53:13 -07001375 try {
1376 final boolean changed = mNetdService.bandwidthEnableDataSaver(enable);
1377 if (changed) {
1378 mDataSaverMode = enable;
1379 } else {
1380 Log.w(TAG, "setDataSaverMode(" + enable + "): netd command silently failed");
1381 }
1382 return changed;
1383 } catch (RemoteException e) {
1384 Log.w(TAG, "setDataSaverMode(" + enable + "): netd command failed", e);
1385 return false;
Felipe Leme29e72ea2016-09-08 13:26:55 -07001386 } finally {
1387 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
Felipe Leme65be3022016-03-22 14:53:13 -07001388 }
1389 }
1390 }
1391
Lorenzo Colitticc7f1db2019-03-18 23:50:34 +09001392 private static UidRangeParcel makeUidRangeParcel(int start, int stop) {
1393 UidRangeParcel range = new UidRangeParcel();
1394 range.start = start;
1395 range.stop = stop;
1396 return range;
1397 }
1398
1399 private static UidRangeParcel[] toStableParcels(UidRange[] ranges) {
1400 UidRangeParcel[] stableRanges = new UidRangeParcel[ranges.length];
1401 for (int i = 0; i < ranges.length; i++) {
1402 stableRanges[i] = makeUidRangeParcel(ranges[i].start, ranges[i].stop);
1403 }
1404 return stableRanges;
1405 }
1406
Felipe Leme65be3022016-03-22 14:53:13 -07001407 @Override
Robin Lee17e61832016-05-09 13:46:28 +01001408 public void setAllowOnlyVpnForUids(boolean add, UidRange[] uidRanges)
1409 throws ServiceSpecificException {
paulhu59148b72019-08-12 16:25:11 +08001410 NetworkStack.checkNetworkStackPermission(mContext);
Robin Lee17e61832016-05-09 13:46:28 +01001411 try {
Lorenzo Colitticc7f1db2019-03-18 23:50:34 +09001412 mNetdService.networkRejectNonSecureVpn(add, toStableParcels(uidRanges));
Robin Lee17e61832016-05-09 13:46:28 +01001413 } catch (ServiceSpecificException e) {
1414 Log.w(TAG, "setAllowOnlyVpnForUids(" + add + ", " + Arrays.toString(uidRanges) + ")"
1415 + ": netd command failed", e);
1416 throw e;
1417 } catch (RemoteException e) {
1418 Log.w(TAG, "setAllowOnlyVpnForUids(" + add + ", " + Arrays.toString(uidRanges) + ")"
1419 + ": netd command failed", e);
1420 throw e.rethrowAsRuntimeException();
1421 }
1422 }
1423
Lorenzo Colitti8c253ad2017-07-19 00:23:44 +09001424 private void applyUidCleartextNetworkPolicy(int uid, int policy) {
Luke Huang473eb872018-07-26 17:33:14 +08001425 final int policyValue;
Lorenzo Colitti8c253ad2017-07-19 00:23:44 +09001426 switch (policy) {
1427 case StrictMode.NETWORK_POLICY_ACCEPT:
Luke Huang473eb872018-07-26 17:33:14 +08001428 policyValue = INetd.PENALTY_POLICY_ACCEPT;
Lorenzo Colitti8c253ad2017-07-19 00:23:44 +09001429 break;
1430 case StrictMode.NETWORK_POLICY_LOG:
Luke Huang473eb872018-07-26 17:33:14 +08001431 policyValue = INetd.PENALTY_POLICY_LOG;
Lorenzo Colitti8c253ad2017-07-19 00:23:44 +09001432 break;
1433 case StrictMode.NETWORK_POLICY_REJECT:
Luke Huang473eb872018-07-26 17:33:14 +08001434 policyValue = INetd.PENALTY_POLICY_REJECT;
Lorenzo Colitti8c253ad2017-07-19 00:23:44 +09001435 break;
1436 default:
1437 throw new IllegalArgumentException("Unknown policy " + policy);
1438 }
1439
1440 try {
Luke Huang473eb872018-07-26 17:33:14 +08001441 mNetdService.strictUidCleartextPenalty(uid, policyValue);
Lorenzo Colitti8c253ad2017-07-19 00:23:44 +09001442 mUidCleartextPolicy.put(uid, policy);
Luke Huang473eb872018-07-26 17:33:14 +08001443 } catch (RemoteException | ServiceSpecificException e) {
1444 throw new IllegalStateException(e);
Lorenzo Colitti8c253ad2017-07-19 00:23:44 +09001445 }
1446 }
1447
Robin Lee17e61832016-05-09 13:46:28 +01001448 @Override
Jeff Sharkey605eb792014-11-04 13:34:06 -08001449 public void setUidCleartextNetworkPolicy(int uid, int policy) {
1450 if (Binder.getCallingUid() != uid) {
paulhu59148b72019-08-12 16:25:11 +08001451 NetworkStack.checkNetworkStackPermission(mContext);
Jeff Sharkey605eb792014-11-04 13:34:06 -08001452 }
1453
1454 synchronized (mQuotaLock) {
1455 final int oldPolicy = mUidCleartextPolicy.get(uid, StrictMode.NETWORK_POLICY_ACCEPT);
1456 if (oldPolicy == policy) {
Lorenzo Colitti8c253ad2017-07-19 00:23:44 +09001457 // This also ensures we won't needlessly apply an ACCEPT policy if we've just
1458 // enabled strict and the underlying iptables rules are empty.
Jeff Sharkey605eb792014-11-04 13:34:06 -08001459 return;
1460 }
1461
Luke Huang473eb872018-07-26 17:33:14 +08001462 // TODO: remove this code after removing prepareNativeDaemon()
Jeff Sharkey605eb792014-11-04 13:34:06 -08001463 if (!mStrictEnabled) {
1464 // Module isn't enabled yet; stash the requested policy away to
1465 // apply later once the daemon is connected.
1466 mUidCleartextPolicy.put(uid, policy);
1467 return;
1468 }
1469
Lorenzo Colitti8c253ad2017-07-19 00:23:44 +09001470 // netd does not keep state on strict mode policies, and cannot replace a non-accept
1471 // policy without deleting it first. Rather than add state to netd, just always send
1472 // it an accept policy when switching between two non-accept policies.
Lorenzo Colitti26364f12017-08-20 11:54:57 +09001473 // TODO: consider keeping state in netd so we can simplify this code.
Lorenzo Colitti8c253ad2017-07-19 00:23:44 +09001474 if (oldPolicy != StrictMode.NETWORK_POLICY_ACCEPT &&
1475 policy != StrictMode.NETWORK_POLICY_ACCEPT) {
Lorenzo Colitti26364f12017-08-20 11:54:57 +09001476 applyUidCleartextNetworkPolicy(uid, StrictMode.NETWORK_POLICY_ACCEPT);
Jeff Sharkey605eb792014-11-04 13:34:06 -08001477 }
Lorenzo Colitti26364f12017-08-20 11:54:57 +09001478
1479 applyUidCleartextNetworkPolicy(uid, policy);
Jeff Sharkey605eb792014-11-04 13:34:06 -08001480 }
1481 }
1482
1483 @Override
Jeff Sharkey63d27a92011-08-03 17:04:22 -07001484 public boolean isBandwidthControlEnabled() {
Luke Huang56a03a02018-09-07 12:02:16 +08001485 return true;
Jeff Sharkey63d27a92011-08-03 17:04:22 -07001486 }
1487
Lorenzo Colitti07f13042017-07-10 19:06:57 +09001488 private class NetdTetheringStatsProvider extends ITetheringStatsProvider.Stub {
1489 @Override
Lorenzo Colittif1912ca2017-08-17 19:23:08 +09001490 public NetworkStats getTetherStats(int how) {
1491 // We only need to return per-UID stats. Per-device stats are already counted by
1492 // interface counters.
1493 if (how != STATS_PER_UID) {
1494 return new NetworkStats(SystemClock.elapsedRealtime(), 0);
1495 }
1496
Luke Huang13b79e82018-09-26 14:53:42 +08001497 final TetherStatsParcel[] tetherStatsVec;
Lorenzo Colitti07f13042017-07-10 19:06:57 +09001498 try {
Luke Huang13b79e82018-09-26 14:53:42 +08001499 tetherStatsVec = mNetdService.tetherGetStats();
Lorenzo Colitti563dc452017-09-01 17:12:34 +09001500 } catch (RemoteException | ServiceSpecificException e) {
1501 throw new IllegalStateException("problem parsing tethering stats: ", e);
Lorenzo Colitti07f13042017-07-10 19:06:57 +09001502 }
Jeff Sharkeye4984be2013-09-10 21:03:27 -07001503
Lorenzo Colitti563dc452017-09-01 17:12:34 +09001504 final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(),
Luke Huang13b79e82018-09-26 14:53:42 +08001505 tetherStatsVec.length);
Lorenzo Colitti563dc452017-09-01 17:12:34 +09001506 final NetworkStats.Entry entry = new NetworkStats.Entry();
1507
Luke Huang13b79e82018-09-26 14:53:42 +08001508 for (TetherStatsParcel tetherStats : tetherStatsVec) {
Jeff Sharkeye4984be2013-09-10 21:03:27 -07001509 try {
Luke Huang13b79e82018-09-26 14:53:42 +08001510 entry.iface = tetherStats.iface;
Jeff Sharkeye4984be2013-09-10 21:03:27 -07001511 entry.uid = UID_TETHERING;
1512 entry.set = SET_DEFAULT;
1513 entry.tag = TAG_NONE;
Luke Huang13b79e82018-09-26 14:53:42 +08001514 entry.rxBytes = tetherStats.rxBytes;
1515 entry.rxPackets = tetherStats.rxPackets;
1516 entry.txBytes = tetherStats.txBytes;
1517 entry.txPackets = tetherStats.txPackets;
Jeff Sharkeye4984be2013-09-10 21:03:27 -07001518 stats.combineValues(entry);
Lorenzo Colitti563dc452017-09-01 17:12:34 +09001519 } catch (ArrayIndexOutOfBoundsException e) {
Luke Huang13b79e82018-09-26 14:53:42 +08001520 throw new IllegalStateException("invalid tethering stats " + e);
Jeff Sharkeye4984be2013-09-10 21:03:27 -07001521 }
1522 }
Lorenzo Colitti563dc452017-09-01 17:12:34 +09001523
Lorenzo Colitti07f13042017-07-10 19:06:57 +09001524 return stats;
1525 }
Lorenzo Colitti50b60fc2017-08-11 13:47:49 +09001526
1527 @Override
1528 public void setInterfaceQuota(String iface, long quotaBytes) {
1529 // Do nothing. netd is already informed of quota changes in setInterfaceQuota.
1530 }
Lorenzo Colitti07f13042017-07-10 19:06:57 +09001531 }
1532
1533 @Override
Lorenzo Colittif1912ca2017-08-17 19:23:08 +09001534 public NetworkStats getNetworkStatsTethering(int how) {
paulhu59148b72019-08-12 16:25:11 +08001535 NetworkStack.checkNetworkStackPermission(mContext);
Lorenzo Colitti07f13042017-07-10 19:06:57 +09001536
1537 final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1);
1538 synchronized (mTetheringStatsProviders) {
1539 for (ITetheringStatsProvider provider: mTetheringStatsProviders.keySet()) {
1540 try {
Lorenzo Colittif1912ca2017-08-17 19:23:08 +09001541 stats.combineAllValues(provider.getTetherStats(how));
Lorenzo Colitti07f13042017-07-10 19:06:57 +09001542 } catch (RemoteException e) {
1543 Log.e(TAG, "Problem reading tethering stats from " +
1544 mTetheringStatsProviders.get(provider) + ": " + e);
1545 }
1546 }
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001547 }
Jeff Sharkeye4984be2013-09-10 21:03:27 -07001548 return stats;
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001549 }
1550
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001551 @Override
Paul Jensen6bc2c2c2014-05-07 15:27:40 -04001552 public void addVpnUidRanges(int netId, UidRange[] ranges) {
paulhu59148b72019-08-12 16:25:11 +08001553 NetworkStack.checkNetworkStackPermission(mContext);
Luke Huang8a462ec2018-08-24 20:33:16 +08001554
1555 try {
Lorenzo Colitticc7f1db2019-03-18 23:50:34 +09001556 mNetdService.networkAddUidRanges(netId, toStableParcels(ranges));
Luke Huang8a462ec2018-08-24 20:33:16 +08001557 } catch (RemoteException | ServiceSpecificException e) {
1558 throw new IllegalStateException(e);
Chad Brubaker3277620a2013-06-12 13:37:30 -07001559 }
1560 }
1561
1562 @Override
Paul Jensen6bc2c2c2014-05-07 15:27:40 -04001563 public void removeVpnUidRanges(int netId, UidRange[] ranges) {
paulhu59148b72019-08-12 16:25:11 +08001564 NetworkStack.checkNetworkStackPermission(mContext);
Luke Huang8a462ec2018-08-24 20:33:16 +08001565 try {
Lorenzo Colitticc7f1db2019-03-18 23:50:34 +09001566 mNetdService.networkRemoveUidRanges(netId, toStableParcels(ranges));
Luke Huang8a462ec2018-08-24 20:33:16 +08001567 } catch (RemoteException | ServiceSpecificException e) {
1568 throw new IllegalStateException(e);
Chad Brubakercca54c42013-06-27 17:41:38 -07001569 }
1570 }
1571
1572 @Override
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001573 public void setFirewallEnabled(boolean enabled) {
Jeff Sharkeyf56e2432012-09-06 17:54:29 -07001574 enforceSystemUid();
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001575 try {
Luke Huanga241db92018-07-31 20:15:24 +08001576 mNetdService.firewallSetFirewallType(
1577 enabled ? INetd.FIREWALL_WHITELIST : INetd.FIREWALL_BLACKLIST);
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001578 mFirewallEnabled = enabled;
Luke Huanga241db92018-07-31 20:15:24 +08001579 } catch (RemoteException | ServiceSpecificException e) {
1580 throw new IllegalStateException(e);
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001581 }
1582 }
1583
1584 @Override
1585 public boolean isFirewallEnabled() {
Jeff Sharkeyf56e2432012-09-06 17:54:29 -07001586 enforceSystemUid();
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001587 return mFirewallEnabled;
1588 }
1589
1590 @Override
Jeff Sharkey2c092982012-08-24 11:44:40 -07001591 public void setFirewallInterfaceRule(String iface, boolean allow) {
Jeff Sharkeyf56e2432012-09-06 17:54:29 -07001592 enforceSystemUid();
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001593 Preconditions.checkState(mFirewallEnabled);
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001594 try {
Luke Huanga241db92018-07-31 20:15:24 +08001595 mNetdService.firewallSetInterfaceRule(iface,
1596 allow ? INetd.FIREWALL_RULE_ALLOW : INetd.FIREWALL_RULE_DENY);
1597 } catch (RemoteException | ServiceSpecificException e) {
1598 throw new IllegalStateException(e);
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001599 }
1600 }
1601
Lorenzo Colitti3fef7232016-04-29 18:00:03 +09001602 private void closeSocketsForFirewallChainLocked(int chain, String chainName) {
Lorenzo Colitti4cb42402016-04-24 12:52:00 +09001603 // UID ranges to close sockets on.
Lorenzo Colitticc7f1db2019-03-18 23:50:34 +09001604 UidRangeParcel[] ranges;
Lorenzo Colitti4cb42402016-04-24 12:52:00 +09001605 // UID ranges whose sockets we won't touch.
1606 int[] exemptUids;
1607
Lorenzo Colitti4cb42402016-04-24 12:52:00 +09001608 int numUids = 0;
Luke Huanga241db92018-07-31 20:15:24 +08001609 if (DBG) Slog.d(TAG, "Closing sockets after enabling chain " + chainName);
Remi NGUYEN VANf9a8c2e2019-02-13 18:28:35 +09001610 if (getFirewallType(chain) == FIREWALL_WHITELIST) {
Lorenzo Colitti4cb42402016-04-24 12:52:00 +09001611 // Close all sockets on all non-system UIDs...
Lorenzo Colitticc7f1db2019-03-18 23:50:34 +09001612 ranges = new UidRangeParcel[] {
Lorenzo Colitti4cb42402016-04-24 12:52:00 +09001613 // TODO: is there a better way of finding all existing users? If so, we could
1614 // specify their ranges here.
Lorenzo Colitticc7f1db2019-03-18 23:50:34 +09001615 makeUidRangeParcel(Process.FIRST_APPLICATION_UID, Integer.MAX_VALUE),
Lorenzo Colitti4cb42402016-04-24 12:52:00 +09001616 };
1617 // ... except for the UIDs that have allow rules.
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001618 synchronized (mRulesLock) {
1619 final SparseIntArray rules = getUidFirewallRulesLR(chain);
1620 exemptUids = new int[rules.size()];
1621 for (int i = 0; i < exemptUids.length; i++) {
Remi NGUYEN VANf9a8c2e2019-02-13 18:28:35 +09001622 if (rules.valueAt(i) == FIREWALL_RULE_ALLOW) {
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001623 exemptUids[numUids] = rules.keyAt(i);
1624 numUids++;
1625 }
Lorenzo Colitti4cb42402016-04-24 12:52:00 +09001626 }
1627 }
1628 // Normally, whitelist chains only contain deny rules, so numUids == exemptUids.length.
1629 // But the code does not guarantee this in any way, and at least in one case - if we add
1630 // a UID rule to the firewall, and then disable the firewall - the chains can contain
1631 // the wrong type of rule. In this case, don't close connections that we shouldn't.
1632 //
1633 // TODO: tighten up this code by ensuring we never set the wrong type of rule, and
1634 // fix setFirewallEnabled to grab mQuotaLock and clear rules.
1635 if (numUids != exemptUids.length) {
1636 exemptUids = Arrays.copyOf(exemptUids, numUids);
1637 }
1638 } else {
1639 // Close sockets for every UID that has a deny rule...
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001640 synchronized (mRulesLock) {
1641 final SparseIntArray rules = getUidFirewallRulesLR(chain);
Lorenzo Colitticc7f1db2019-03-18 23:50:34 +09001642 ranges = new UidRangeParcel[rules.size()];
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001643 for (int i = 0; i < ranges.length; i++) {
Remi NGUYEN VANf9a8c2e2019-02-13 18:28:35 +09001644 if (rules.valueAt(i) == FIREWALL_RULE_DENY) {
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001645 int uid = rules.keyAt(i);
Lorenzo Colitticc7f1db2019-03-18 23:50:34 +09001646 ranges[numUids] = makeUidRangeParcel(uid, uid);
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001647 numUids++;
1648 }
Lorenzo Colitti4cb42402016-04-24 12:52:00 +09001649 }
1650 }
1651 // As above; usually numUids == ranges.length, but not always.
1652 if (numUids != ranges.length) {
1653 ranges = Arrays.copyOf(ranges, numUids);
1654 }
1655 // ... with no exceptions.
1656 exemptUids = new int[0];
1657 }
1658
1659 try {
1660 mNetdService.socketDestroy(ranges, exemptUids);
1661 } catch(RemoteException | ServiceSpecificException e) {
1662 Slog.e(TAG, "Error closing sockets after enabling chain " + chainName + ": " + e);
1663 }
1664 }
1665
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001666 @Override
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07001667 public void setFirewallChainEnabled(int chain, boolean enable) {
Jeff Sharkeyf56e2432012-09-06 17:54:29 -07001668 enforceSystemUid();
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07001669 synchronized (mQuotaLock) {
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001670 synchronized (mRulesLock) {
1671 if (getFirewallChainState(chain) == enable) {
1672 // All is the same, nothing to do. This relies on the fact that netd has child
1673 // chains default detached.
1674 return;
1675 }
1676 setFirewallChainState(chain, enable);
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07001677 }
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07001678
Luke Huang615e1022018-10-25 11:54:05 +09001679 final String chainName = getFirewallChainName(chain);
Luke Huanga241db92018-07-31 20:15:24 +08001680 if (chain == FIREWALL_CHAIN_NONE) {
Luke Huang615e1022018-10-25 11:54:05 +09001681 throw new IllegalArgumentException("Bad child chain: " + chainName);
Lorenzo Colitti4cb42402016-04-24 12:52:00 +09001682 }
1683
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07001684 try {
Luke Huanga241db92018-07-31 20:15:24 +08001685 mNetdService.firewallEnableChildChain(chain, enable);
1686 } catch (RemoteException | ServiceSpecificException e) {
1687 throw new IllegalStateException(e);
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07001688 }
Lorenzo Colitti4cb42402016-04-24 12:52:00 +09001689
1690 // Close any sockets that were opened by the affected UIDs. This has to be done after
1691 // disabling network connectivity, in case they react to the socket close by reopening
1692 // the connection and race with the iptables commands that enable the firewall. All
1693 // whitelist and blacklist chains allow RSTs through.
1694 if (enable) {
Luke Huang615e1022018-10-25 11:54:05 +09001695 closeSocketsForFirewallChainLocked(chain, chainName);
Lorenzo Colitti4cb42402016-04-24 12:52:00 +09001696 }
Amith Yamasani15e472352015-04-24 19:06:07 -07001697 }
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07001698 }
1699
Luke Huanga241db92018-07-31 20:15:24 +08001700 private String getFirewallChainName(int chain) {
1701 switch (chain) {
1702 case FIREWALL_CHAIN_STANDBY:
1703 return FIREWALL_CHAIN_NAME_STANDBY;
1704 case FIREWALL_CHAIN_DOZABLE:
1705 return FIREWALL_CHAIN_NAME_DOZABLE;
1706 case FIREWALL_CHAIN_POWERSAVE:
1707 return FIREWALL_CHAIN_NAME_POWERSAVE;
1708 default:
1709 throw new IllegalArgumentException("Bad child chain: " + chain);
1710 }
1711 }
1712
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07001713 private int getFirewallType(int chain) {
1714 switch (chain) {
1715 case FIREWALL_CHAIN_STANDBY:
Remi NGUYEN VANf9a8c2e2019-02-13 18:28:35 +09001716 return FIREWALL_BLACKLIST;
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07001717 case FIREWALL_CHAIN_DOZABLE:
Remi NGUYEN VANf9a8c2e2019-02-13 18:28:35 +09001718 return FIREWALL_WHITELIST;
Felipe Leme011b98f2016-02-10 17:28:31 -08001719 case FIREWALL_CHAIN_POWERSAVE:
Remi NGUYEN VANf9a8c2e2019-02-13 18:28:35 +09001720 return FIREWALL_WHITELIST;
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07001721 default:
Remi NGUYEN VANf9a8c2e2019-02-13 18:28:35 +09001722 return isFirewallEnabled() ? FIREWALL_WHITELIST : FIREWALL_BLACKLIST;
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07001723 }
1724 }
1725
1726 @Override
1727 public void setFirewallUidRules(int chain, int[] uids, int[] rules) {
1728 enforceSystemUid();
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07001729 synchronized (mQuotaLock) {
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001730 synchronized (mRulesLock) {
1731 SparseIntArray uidFirewallRules = getUidFirewallRulesLR(chain);
1732 SparseIntArray newRules = new SparseIntArray();
1733 // apply new set of rules
1734 for (int index = uids.length - 1; index >= 0; --index) {
1735 int uid = uids[index];
1736 int rule = rules[index];
1737 updateFirewallUidRuleLocked(chain, uid, rule);
1738 newRules.put(uid, rule);
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07001739 }
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001740 // collect the rules to remove.
1741 SparseIntArray rulesToRemove = new SparseIntArray();
1742 for (int index = uidFirewallRules.size() - 1; index >= 0; --index) {
1743 int uid = uidFirewallRules.keyAt(index);
1744 if (newRules.indexOfKey(uid) < 0) {
1745 rulesToRemove.put(uid, FIREWALL_RULE_DEFAULT);
1746 }
1747 }
1748 // remove dead rules
1749 for (int index = rulesToRemove.size() - 1; index >= 0; --index) {
1750 int uid = rulesToRemove.keyAt(index);
1751 updateFirewallUidRuleLocked(chain, uid, FIREWALL_RULE_DEFAULT);
1752 }
Felipe Lemea701cad2016-05-12 09:58:14 -07001753 }
1754 try {
1755 switch (chain) {
1756 case FIREWALL_CHAIN_DOZABLE:
1757 mNetdService.firewallReplaceUidChain("fw_dozable", true, uids);
1758 break;
1759 case FIREWALL_CHAIN_STANDBY:
1760 mNetdService.firewallReplaceUidChain("fw_standby", false, uids);
1761 break;
1762 case FIREWALL_CHAIN_POWERSAVE:
1763 mNetdService.firewallReplaceUidChain("fw_powersave", true, uids);
1764 break;
1765 case FIREWALL_CHAIN_NONE:
1766 default:
1767 Slog.d(TAG, "setFirewallUidRules() called on invalid chain: " + chain);
1768 }
1769 } catch (RemoteException e) {
1770 Slog.w(TAG, "Error flushing firewall chain " + chain, e);
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07001771 }
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07001772 }
1773 }
1774
1775 @Override
1776 public void setFirewallUidRule(int chain, int uid, int rule) {
1777 enforceSystemUid();
Felipe Lemea701cad2016-05-12 09:58:14 -07001778 synchronized (mQuotaLock) {
1779 setFirewallUidRuleLocked(chain, uid, rule);
1780 }
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07001781 }
1782
Felipe Lemea701cad2016-05-12 09:58:14 -07001783 private void setFirewallUidRuleLocked(int chain, int uid, int rule) {
1784 if (updateFirewallUidRuleLocked(chain, uid, rule)) {
Luke Huanga241db92018-07-31 20:15:24 +08001785 final int ruleType = getFirewallRuleType(chain, rule);
Amith Yamasani15e472352015-04-24 19:06:07 -07001786 try {
Luke Huanga241db92018-07-31 20:15:24 +08001787 mNetdService.firewallSetUidRule(chain, uid, ruleType);
1788 } catch (RemoteException | ServiceSpecificException e) {
1789 throw new IllegalStateException(e);
Amith Yamasani15e472352015-04-24 19:06:07 -07001790 }
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001791 }
1792 }
1793
Felipe Lemea701cad2016-05-12 09:58:14 -07001794 // TODO: now that netd supports batching, NMS should not keep these data structures anymore...
1795 private boolean updateFirewallUidRuleLocked(int chain, int uid, int rule) {
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001796 synchronized (mRulesLock) {
1797 SparseIntArray uidFirewallRules = getUidFirewallRulesLR(chain);
Felipe Lemea701cad2016-05-12 09:58:14 -07001798
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001799 final int oldUidFirewallRule = uidFirewallRules.get(uid, FIREWALL_RULE_DEFAULT);
1800 if (DBG) {
1801 Slog.d(TAG, "oldRule = " + oldUidFirewallRule
1802 + ", newRule=" + rule + " for uid=" + uid + " on chain " + chain);
1803 }
1804 if (oldUidFirewallRule == rule) {
1805 if (DBG) Slog.d(TAG, "!!!!! Skipping change");
1806 // TODO: eventually consider throwing
1807 return false;
1808 }
Felipe Lemea701cad2016-05-12 09:58:14 -07001809
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001810 String ruleName = getFirewallRuleName(chain, rule);
1811 String oldRuleName = getFirewallRuleName(chain, oldUidFirewallRule);
Felipe Lemea701cad2016-05-12 09:58:14 -07001812
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001813 if (rule == NetworkPolicyManager.FIREWALL_RULE_DEFAULT) {
1814 uidFirewallRules.delete(uid);
1815 } else {
1816 uidFirewallRules.put(uid, rule);
1817 }
1818 return !ruleName.equals(oldRuleName);
Felipe Lemea701cad2016-05-12 09:58:14 -07001819 }
Felipe Lemea701cad2016-05-12 09:58:14 -07001820 }
1821
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07001822 private @NonNull String getFirewallRuleName(int chain, int rule) {
1823 String ruleName;
Remi NGUYEN VANf9a8c2e2019-02-13 18:28:35 +09001824 if (getFirewallType(chain) == FIREWALL_WHITELIST) {
1825 if (rule == FIREWALL_RULE_ALLOW) {
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07001826 ruleName = "allow";
1827 } else {
1828 ruleName = "deny";
1829 }
1830 } else { // Blacklist mode
Remi NGUYEN VANf9a8c2e2019-02-13 18:28:35 +09001831 if (rule == FIREWALL_RULE_DENY) {
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07001832 ruleName = "deny";
1833 } else {
1834 ruleName = "allow";
1835 }
1836 }
1837 return ruleName;
1838 }
1839
Andreas Gampeaae5aa32018-07-20 12:55:38 -07001840 @GuardedBy("mRulesLock")
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001841 private @NonNull SparseIntArray getUidFirewallRulesLR(int chain) {
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07001842 switch (chain) {
1843 case FIREWALL_CHAIN_STANDBY:
1844 return mUidFirewallStandbyRules;
1845 case FIREWALL_CHAIN_DOZABLE:
1846 return mUidFirewallDozableRules;
Felipe Leme011b98f2016-02-10 17:28:31 -08001847 case FIREWALL_CHAIN_POWERSAVE:
1848 return mUidFirewallPowerSaveRules;
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07001849 case FIREWALL_CHAIN_NONE:
1850 return mUidFirewallRules;
1851 default:
1852 throw new IllegalArgumentException("Unknown chain:" + chain);
1853 }
1854 }
1855
Luke Huanga241db92018-07-31 20:15:24 +08001856 private int getFirewallRuleType(int chain, int rule) {
Luke Huang615e1022018-10-25 11:54:05 +09001857 if (rule == NetworkPolicyManager.FIREWALL_RULE_DEFAULT) {
Remi NGUYEN VANf9a8c2e2019-02-13 18:28:35 +09001858 return getFirewallType(chain) == FIREWALL_WHITELIST
Luke Huang615e1022018-10-25 11:54:05 +09001859 ? INetd.FIREWALL_RULE_DENY : INetd.FIREWALL_RULE_ALLOW;
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07001860 }
Luke Huang615e1022018-10-25 11:54:05 +09001861 return rule;
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07001862 }
1863
Jeff Sharkeyf56e2432012-09-06 17:54:29 -07001864 private static void enforceSystemUid() {
1865 final int uid = Binder.getCallingUid();
1866 if (uid != Process.SYSTEM_UID) {
1867 throw new SecurityException("Only available to AID_SYSTEM");
1868 }
1869 }
1870
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001871 @Override
Dianne Hackborn77b987f2014-02-26 16:20:52 -08001872 public void registerNetworkActivityListener(INetworkActivityListener listener) {
1873 mNetworkActivityListeners.register(listener);
1874 }
1875
1876 @Override
1877 public void unregisterNetworkActivityListener(INetworkActivityListener listener) {
1878 mNetworkActivityListeners.unregister(listener);
1879 }
1880
1881 @Override
1882 public boolean isNetworkActive() {
1883 synchronized (mNetworkActivityListeners) {
1884 return mNetworkActive || mActiveIdleTimers.isEmpty();
1885 }
1886 }
1887
1888 private void reportNetworkActive() {
1889 final int length = mNetworkActivityListeners.beginBroadcast();
Robert Greenwalt2c9f5472014-04-21 14:50:28 -07001890 try {
1891 for (int i = 0; i < length; i++) {
1892 try {
1893 mNetworkActivityListeners.getBroadcastItem(i).onNetworkActive();
Felipe Leme03e689d2016-03-02 16:17:38 -08001894 } catch (RemoteException | RuntimeException e) {
Robert Greenwalt2c9f5472014-04-21 14:50:28 -07001895 }
Dianne Hackborn77b987f2014-02-26 16:20:52 -08001896 }
Robert Greenwalt2c9f5472014-04-21 14:50:28 -07001897 } finally {
1898 mNetworkActivityListeners.finishBroadcast();
Dianne Hackborn77b987f2014-02-26 16:20:52 -08001899 }
Dianne Hackborn77b987f2014-02-26 16:20:52 -08001900 }
1901
Jeff Sharkey47eb1022011-08-25 17:48:52 -07001902 @Override
1903 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -06001904 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
Jeff Sharkey47eb1022011-08-25 17:48:52 -07001905
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07001906 pw.print("mMobileActivityFromRadio="); pw.print(mMobileActivityFromRadio);
1907 pw.print(" mLastPowerStateFromRadio="); pw.println(mLastPowerStateFromRadio);
1908 pw.print("mNetworkActive="); pw.println(mNetworkActive);
Jeff Sharkey47eb1022011-08-25 17:48:52 -07001909
1910 synchronized (mQuotaLock) {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001911 pw.print("Active quota ifaces: "); pw.println(mActiveQuotas.toString());
1912 pw.print("Active alert ifaces: "); pw.println(mActiveAlerts.toString());
Felipe Leme65be3022016-03-22 14:53:13 -07001913 pw.print("Data saver mode: "); pw.println(mDataSaverMode);
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001914 synchronized (mRulesLock) {
1915 dumpUidRuleOnQuotaLocked(pw, "blacklist", mUidRejectOnMetered);
1916 dumpUidRuleOnQuotaLocked(pw, "whitelist", mUidAllowOnMetered);
1917 }
Jeff Sharkey47eb1022011-08-25 17:48:52 -07001918 }
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001919
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001920 synchronized (mRulesLock) {
Felipe Leme011b98f2016-02-10 17:28:31 -08001921 dumpUidFirewallRule(pw, "", mUidFirewallRules);
Amith Yamasani15e472352015-04-24 19:06:07 -07001922
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001923 pw.print("UID firewall standby chain enabled: "); pw.println(
1924 getFirewallChainState(FIREWALL_CHAIN_STANDBY));
Felipe Leme011b98f2016-02-10 17:28:31 -08001925 dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_STANDBY, mUidFirewallStandbyRules);
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07001926
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001927 pw.print("UID firewall dozable chain enabled: "); pw.println(
1928 getFirewallChainState(FIREWALL_CHAIN_DOZABLE));
Felipe Leme011b98f2016-02-10 17:28:31 -08001929 dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_DOZABLE, mUidFirewallDozableRules);
Felipe Leme011b98f2016-02-10 17:28:31 -08001930
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001931 pw.println("UID firewall powersave chain enabled: " +
1932 getFirewallChainState(FIREWALL_CHAIN_POWERSAVE));
Felipe Leme011b98f2016-02-10 17:28:31 -08001933 dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_POWERSAVE, mUidFirewallPowerSaveRules);
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07001934 }
1935
Dianne Hackborn77b987f2014-02-26 16:20:52 -08001936 synchronized (mIdleTimerLock) {
1937 pw.println("Idle timers:");
1938 for (HashMap.Entry<String, IdleTimerParams> ent : mActiveIdleTimers.entrySet()) {
1939 pw.print(" "); pw.print(ent.getKey()); pw.println(":");
1940 IdleTimerParams params = ent.getValue();
1941 pw.print(" timeout="); pw.print(params.timeout);
1942 pw.print(" type="); pw.print(params.type);
1943 pw.print(" networkCount="); pw.println(params.networkCount);
1944 }
1945 }
1946
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001947 pw.print("Firewall enabled: "); pw.println(mFirewallEnabled);
Felipe Leme65be3022016-03-22 14:53:13 -07001948 pw.print("Netd service status: " );
1949 if (mNetdService == null) {
1950 pw.println("disconnected");
1951 } else {
1952 try {
1953 final boolean alive = mNetdService.isAlive();
1954 pw.println(alive ? "alive": "dead");
1955 } catch (RemoteException e) {
1956 pw.println("unreachable");
1957 }
1958 }
1959 }
1960
1961 private void dumpUidRuleOnQuotaLocked(PrintWriter pw, String name, SparseBooleanArray list) {
1962 pw.print("UID bandwith control ");
1963 pw.print(name);
1964 pw.print(" rule: [");
1965 final int size = list.size();
1966 for (int i = 0; i < size; i++) {
1967 pw.print(list.keyAt(i));
1968 if (i < size - 1) pw.print(",");
1969 }
1970 pw.println("]");
Jeff Sharkey47eb1022011-08-25 17:48:52 -07001971 }
Robert Greenwalt9ba9c582014-03-19 17:56:12 -07001972
Felipe Leme011b98f2016-02-10 17:28:31 -08001973 private void dumpUidFirewallRule(PrintWriter pw, String name, SparseIntArray rules) {
Lorenzo Colitti4cb42402016-04-24 12:52:00 +09001974 pw.print("UID firewall ");
Felipe Leme011b98f2016-02-10 17:28:31 -08001975 pw.print(name);
1976 pw.print(" rule: [");
1977 final int size = rules.size();
1978 for (int i = 0; i < size; i++) {
1979 pw.print(rules.keyAt(i));
1980 pw.print(":");
1981 pw.print(rules.valueAt(i));
1982 if (i < size - 1) pw.print(",");
1983 }
1984 pw.println("]");
1985 }
1986
Robert Greenwalt568891d2014-04-04 13:38:00 -07001987 @Override
Paul Jensen992f2522014-04-28 10:33:11 -04001988 public void addInterfaceToNetwork(String iface, int netId) {
Luke Huang8a462ec2018-08-24 20:33:16 +08001989 modifyInterfaceInNetwork(MODIFY_OPERATION_ADD, netId, iface);
Paul Jensen992f2522014-04-28 10:33:11 -04001990 }
1991
1992 @Override
1993 public void removeInterfaceFromNetwork(String iface, int netId) {
Luke Huang8a462ec2018-08-24 20:33:16 +08001994 modifyInterfaceInNetwork(MODIFY_OPERATION_REMOVE, netId, iface);
Sreeram Ramachandrana77760d2014-07-17 17:09:07 -07001995 }
Paul Jensen992f2522014-04-28 10:33:11 -04001996
Luke Huang8a462ec2018-08-24 20:33:16 +08001997 private void modifyInterfaceInNetwork(boolean add, int netId, String iface) {
paulhu59148b72019-08-12 16:25:11 +08001998 NetworkStack.checkNetworkStackPermission(mContext);
Paul Jensen992f2522014-04-28 10:33:11 -04001999 try {
Luke Huang8a462ec2018-08-24 20:33:16 +08002000 if (add) {
2001 mNetdService.networkAddInterface(netId, iface);
2002 } else {
2003 mNetdService.networkRemoveInterface(netId, iface);
2004 }
2005 } catch (RemoteException | ServiceSpecificException e) {
2006 throw new IllegalStateException(e);
Paul Jensen992f2522014-04-28 10:33:11 -04002007 }
2008 }
2009
2010 @Override
Robert Greenwalt913c8952014-04-07 17:36:35 -07002011 public void addLegacyRouteForNetId(int netId, RouteInfo routeInfo, int uid) {
paulhu59148b72019-08-12 16:25:11 +08002012 NetworkStack.checkNetworkStackPermission(mContext);
Robert Greenwalt568891d2014-04-04 13:38:00 -07002013
Sreeram Ramachandrancc91c7b2014-06-03 18:41:43 -07002014 final LinkAddress la = routeInfo.getDestinationLinkAddress();
Luke Huang8a462ec2018-08-24 20:33:16 +08002015 final String ifName = routeInfo.getInterface();
2016 final String dst = la.toString();
2017 final String nextHop;
Robert Greenwalt568891d2014-04-04 13:38:00 -07002018
Luke Huang8a462ec2018-08-24 20:33:16 +08002019 if (routeInfo.hasGateway()) {
2020 nextHop = routeInfo.getGateway().getHostAddress();
2021 } else {
2022 nextHop = "";
2023 }
Robert Greenwalt568891d2014-04-04 13:38:00 -07002024 try {
Luke Huang8a462ec2018-08-24 20:33:16 +08002025 mNetdService.networkAddLegacyRoute(netId, ifName, dst, nextHop, uid);
2026 } catch (RemoteException | ServiceSpecificException e) {
2027 throw new IllegalStateException(e);
Robert Greenwalt568891d2014-04-04 13:38:00 -07002028 }
2029 }
2030
2031 @Override
Sreeram Ramachandranf047f2a2014-04-15 16:04:26 -07002032 public void setDefaultNetId(int netId) {
paulhu59148b72019-08-12 16:25:11 +08002033 NetworkStack.checkNetworkStackPermission(mContext);
Robert Greenwalt568891d2014-04-04 13:38:00 -07002034
2035 try {
Luke Huang8a462ec2018-08-24 20:33:16 +08002036 mNetdService.networkSetDefault(netId);
2037 } catch (RemoteException | ServiceSpecificException e) {
2038 throw new IllegalStateException(e);
Robert Greenwalt568891d2014-04-04 13:38:00 -07002039 }
2040 }
2041
2042 @Override
2043 public void clearDefaultNetId() {
paulhu59148b72019-08-12 16:25:11 +08002044 NetworkStack.checkNetworkStackPermission(mContext);
Robert Greenwalt568891d2014-04-04 13:38:00 -07002045
2046 try {
Luke Huang8a462ec2018-08-24 20:33:16 +08002047 mNetdService.networkClearDefault();
2048 } catch (RemoteException | ServiceSpecificException e) {
2049 throw new IllegalStateException(e);
Robert Greenwalt568891d2014-04-04 13:38:00 -07002050 }
2051 }
2052
2053 @Override
Luke Huang8a462ec2018-08-24 20:33:16 +08002054 public void setNetworkPermission(int netId, int permission) {
paulhu59148b72019-08-12 16:25:11 +08002055 NetworkStack.checkNetworkStackPermission(mContext);
Paul Jensen487ffe72015-07-24 15:57:11 -04002056
2057 try {
Luke Huang8a462ec2018-08-24 20:33:16 +08002058 mNetdService.networkSetPermissionForNetwork(netId, permission);
2059 } catch (RemoteException | ServiceSpecificException e) {
2060 throw new IllegalStateException(e);
Paul Jensen487ffe72015-07-24 15:57:11 -04002061 }
2062 }
2063
Paul Jensen6bc2c2c2014-05-07 15:27:40 -04002064 @Override
2065 public void allowProtect(int uid) {
paulhu59148b72019-08-12 16:25:11 +08002066 NetworkStack.checkNetworkStackPermission(mContext);
Paul Jensen6bc2c2c2014-05-07 15:27:40 -04002067
2068 try {
Luke Huang8a462ec2018-08-24 20:33:16 +08002069 mNetdService.networkSetProtectAllow(uid);
2070 } catch (RemoteException | ServiceSpecificException e) {
2071 throw new IllegalStateException(e);
Paul Jensen6bc2c2c2014-05-07 15:27:40 -04002072 }
2073 }
2074
2075 @Override
2076 public void denyProtect(int uid) {
paulhu59148b72019-08-12 16:25:11 +08002077 NetworkStack.checkNetworkStackPermission(mContext);
Paul Jensen6bc2c2c2014-05-07 15:27:40 -04002078
2079 try {
Luke Huang8a462ec2018-08-24 20:33:16 +08002080 mNetdService.networkSetProtectDeny(uid);
2081 } catch (RemoteException | ServiceSpecificException e) {
2082 throw new IllegalStateException(e);
Paul Jensen6bc2c2c2014-05-07 15:27:40 -04002083 }
2084 }
2085
Sreeram Ramachandrana77760d2014-07-17 17:09:07 -07002086 @Override
2087 public void addInterfaceToLocalNetwork(String iface, List<RouteInfo> routes) {
Luke Huang706d7ab2018-10-16 15:42:15 +08002088 modifyInterfaceInNetwork(MODIFY_OPERATION_ADD, INetd.LOCAL_NET_ID, iface);
markchiena9d9ef82020-01-07 14:43:17 +08002089 // modifyInterfaceInNetwork already check calling permission.
2090 RouteUtils.addRoutesToLocalNetwork(mNetdService, iface, routes);
Sreeram Ramachandrana77760d2014-07-17 17:09:07 -07002091 }
2092
2093 @Override
2094 public void removeInterfaceFromLocalNetwork(String iface) {
Luke Huang706d7ab2018-10-16 15:42:15 +08002095 modifyInterfaceInNetwork(MODIFY_OPERATION_REMOVE, INetd.LOCAL_NET_ID, iface);
Sreeram Ramachandrana77760d2014-07-17 17:09:07 -07002096 }
Erik Kline6599ee82016-07-17 21:28:39 +09002097
2098 @Override
2099 public int removeRoutesFromLocalNetwork(List<RouteInfo> routes) {
markchiena9d9ef82020-01-07 14:43:17 +08002100 NetworkStack.checkNetworkStackPermission(mContext);
2101 return RouteUtils.removeRoutesFromLocalNetwork(mNetdService, routes);
Erik Kline6599ee82016-07-17 21:28:39 +09002102 }
Sudheer Shanka62f5c172017-03-17 16:25:55 -07002103
Sudheer Shankab8f23162017-08-04 13:30:10 -07002104 @Override
2105 public boolean isNetworkRestricted(int uid) {
paulhu59148b72019-08-12 16:25:11 +08002106 mContext.enforceCallingOrSelfPermission(OBSERVE_NETWORK_POLICY, TAG);
Sudheer Shankab8f23162017-08-04 13:30:10 -07002107 return isNetworkRestrictedInternal(uid);
2108 }
2109
2110 private boolean isNetworkRestrictedInternal(int uid) {
2111 synchronized (mRulesLock) {
2112 if (getFirewallChainState(FIREWALL_CHAIN_STANDBY)
2113 && mUidFirewallStandbyRules.get(uid) == FIREWALL_RULE_DENY) {
2114 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of app standby mode");
2115 return true;
2116 }
2117 if (getFirewallChainState(FIREWALL_CHAIN_DOZABLE)
2118 && mUidFirewallDozableRules.get(uid) != FIREWALL_RULE_ALLOW) {
2119 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of device idle mode");
2120 return true;
2121 }
2122 if (getFirewallChainState(FIREWALL_CHAIN_POWERSAVE)
2123 && mUidFirewallPowerSaveRules.get(uid) != FIREWALL_RULE_ALLOW) {
2124 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of power saver mode");
2125 return true;
2126 }
2127 if (mUidRejectOnMetered.get(uid)) {
2128 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of no metered data"
2129 + " in the background");
2130 return true;
2131 }
2132 if (mDataSaverMode && !mUidAllowOnMetered.get(uid)) {
2133 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of data saver mode");
2134 return true;
2135 }
2136 return false;
2137 }
2138 }
2139
Sudheer Shanka62f5c172017-03-17 16:25:55 -07002140 private void setFirewallChainState(int chain, boolean state) {
2141 synchronized (mRulesLock) {
2142 mFirewallChainStates.put(chain, state);
2143 }
2144 }
2145
2146 private boolean getFirewallChainState(int chain) {
2147 synchronized (mRulesLock) {
2148 return mFirewallChainStates.get(chain);
2149 }
2150 }
2151
2152 @VisibleForTesting
2153 class LocalService extends NetworkManagementInternal {
2154 @Override
2155 public boolean isNetworkRestrictedForUid(int uid) {
Sudheer Shankab8f23162017-08-04 13:30:10 -07002156 return isNetworkRestrictedInternal(uid);
Sudheer Shanka62f5c172017-03-17 16:25:55 -07002157 }
2158 }
2159
2160 @VisibleForTesting
2161 Injector getInjector() {
2162 return new Injector();
2163 }
2164
2165 @VisibleForTesting
2166 class Injector {
2167 void setDataSaverMode(boolean dataSaverMode) {
2168 mDataSaverMode = dataSaverMode;
2169 }
2170
2171 void setFirewallChainState(int chain, boolean state) {
2172 NetworkManagementService.this.setFirewallChainState(chain, state);
2173 }
2174
2175 void setFirewallRule(int chain, int uid, int rule) {
2176 synchronized (mRulesLock) {
2177 getUidFirewallRulesLR(chain).put(uid, rule);
2178 }
2179 }
2180
2181 void setUidOnMeteredNetworkList(boolean blacklist, int uid, boolean enable) {
2182 synchronized (mRulesLock) {
2183 if (blacklist) {
2184 mUidRejectOnMetered.put(uid, enable);
2185 } else {
2186 mUidAllowOnMetered.put(uid, enable);
2187 }
2188 }
2189 }
2190
2191 void reset() {
2192 synchronized (mRulesLock) {
2193 setDataSaverMode(false);
2194 final int[] chains = {
2195 FIREWALL_CHAIN_DOZABLE,
2196 FIREWALL_CHAIN_STANDBY,
2197 FIREWALL_CHAIN_POWERSAVE
2198 };
2199 for (int chain : chains) {
2200 setFirewallChainState(chain, false);
2201 getUidFirewallRulesLR(chain).clear();
2202 }
2203 mUidAllowOnMetered.clear();
2204 mUidRejectOnMetered.clear();
2205 }
2206 }
2207 }
San Mehat873f2142010-01-14 10:25:07 -08002208}