1 /*
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 
17 package com.android.server;
18 
19 import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
20 import static android.Manifest.permission.NETWORK_SETTINGS;
21 import static android.Manifest.permission.OBSERVE_NETWORK_POLICY;
22 import static android.Manifest.permission.SHUTDOWN;
23 import static android.net.INetd.FIREWALL_BLACKLIST;
24 import static android.net.INetd.FIREWALL_CHAIN_DOZABLE;
25 import static android.net.INetd.FIREWALL_CHAIN_NONE;
26 import static android.net.INetd.FIREWALL_CHAIN_POWERSAVE;
27 import static android.net.INetd.FIREWALL_CHAIN_STANDBY;
28 import static android.net.INetd.FIREWALL_RULE_ALLOW;
29 import static android.net.INetd.FIREWALL_RULE_DENY;
30 import static android.net.INetd.FIREWALL_WHITELIST;
31 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_DOZABLE;
32 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_POWERSAVE;
33 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_STANDBY;
34 import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
35 import static android.net.NetworkStats.SET_DEFAULT;
36 import static android.net.NetworkStats.STATS_PER_UID;
37 import static android.net.NetworkStats.TAG_NONE;
38 import static android.net.TrafficStats.UID_TETHERING;
39 
40 import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED;
41 
42 import android.annotation.NonNull;
43 import android.app.ActivityManager;
44 import android.content.Context;
45 import android.net.ConnectivityManager;
46 import android.net.INetd;
47 import android.net.INetdUnsolicitedEventListener;
48 import android.net.INetworkManagementEventObserver;
49 import android.net.ITetheringStatsProvider;
50 import android.net.InetAddresses;
51 import android.net.InterfaceConfiguration;
52 import android.net.InterfaceConfigurationParcel;
53 import android.net.IpPrefix;
54 import android.net.LinkAddress;
55 import android.net.Network;
56 import android.net.NetworkPolicyManager;
57 import android.net.NetworkStack;
58 import android.net.NetworkStats;
59 import android.net.NetworkUtils;
60 import android.net.RouteInfo;
61 import android.net.TetherStatsParcel;
62 import android.net.UidRange;
63 import android.net.UidRangeParcel;
64 import android.net.shared.NetdUtils;
65 import android.net.shared.RouteUtils;
66 import android.net.shared.RouteUtils.ModifyOperation;
67 import android.net.util.NetdService;
68 import android.os.BatteryStats;
69 import android.os.Binder;
70 import android.os.Handler;
71 import android.os.IBinder;
72 import android.os.INetworkActivityListener;
73 import android.os.INetworkManagementService;
74 import android.os.Process;
75 import android.os.RemoteCallbackList;
76 import android.os.RemoteException;
77 import android.os.ServiceManager;
78 import android.os.ServiceSpecificException;
79 import android.os.StrictMode;
80 import android.os.SystemClock;
81 import android.os.SystemProperties;
82 import android.os.Trace;
83 import android.telephony.DataConnectionRealTimeInfo;
84 import android.text.TextUtils;
85 import android.util.Log;
86 import android.util.Slog;
87 import android.util.SparseBooleanArray;
88 import android.util.SparseIntArray;
89 
90 import com.android.internal.annotations.GuardedBy;
91 import com.android.internal.annotations.VisibleForTesting;
92 import com.android.internal.app.IBatteryStats;
93 import com.android.internal.util.DumpUtils;
94 import com.android.internal.util.FrameworkStatsLog;
95 import com.android.internal.util.HexDump;
96 import com.android.internal.util.Preconditions;
97 
98 import com.google.android.collect.Maps;
99 
100 import java.io.BufferedReader;
101 import java.io.DataInputStream;
102 import java.io.FileDescriptor;
103 import java.io.FileInputStream;
104 import java.io.IOException;
105 import java.io.InputStreamReader;
106 import java.io.PrintWriter;
107 import java.net.InetAddress;
108 import java.net.InterfaceAddress;
109 import java.util.ArrayList;
110 import java.util.Arrays;
111 import java.util.HashMap;
112 import java.util.List;
113 import java.util.Map;
114 import java.util.Objects;
115 
116 /**
117  * @hide
118  */
119 public class NetworkManagementService extends INetworkManagementService.Stub {
120 
121     /**
122      * Helper class that encapsulates NetworkManagementService dependencies and makes them
123      * easier to mock in unit tests.
124      */
125     static class SystemServices {
getService(String name)126         public IBinder getService(String name) {
127             return ServiceManager.getService(name);
128         }
registerLocalService(NetworkManagementInternal nmi)129         public void registerLocalService(NetworkManagementInternal nmi) {
130             LocalServices.addService(NetworkManagementInternal.class, nmi);
131         }
getNetd()132         public INetd getNetd() {
133             return NetdService.get();
134         }
135     }
136 
137     private static final String TAG = "NetworkManagement";
138     private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
139 
140     private static final int MAX_UID_RANGES_PER_COMMAND = 10;
141 
142     /**
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 
148     static final int DAEMON_MSG_MOBILE_CONN_REAL_TIME_INFO = 1;
149 
150     static final boolean MODIFY_OPERATION_ADD = true;
151     static final boolean MODIFY_OPERATION_REMOVE = false;
152 
153     /**
154      * Binder context for this service
155      */
156     private final Context mContext;
157 
158     private final Handler mDaemonHandler;
159 
160     private final SystemServices mServices;
161 
162     private INetd mNetdService;
163 
164     private final NetdUnsolicitedEventListener mNetdUnsolicitedEventListener;
165 
166     private IBatteryStats mBatteryStats;
167 
168     private final RemoteCallbackList<INetworkManagementEventObserver> mObservers =
169             new RemoteCallbackList<>();
170 
171     @GuardedBy("mTetheringStatsProviders")
172     private final HashMap<ITetheringStatsProvider, String>
173             mTetheringStatsProviders = Maps.newHashMap();
174 
175     /**
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      */
179     private final Object mQuotaLock = new Object();
180     private final Object mRulesLock = new Object();
181 
182     /** Set of interfaces with active quotas. */
183     @GuardedBy("mQuotaLock")
184     private HashMap<String, Long> mActiveQuotas = Maps.newHashMap();
185     /** Set of interfaces with active alerts. */
186     @GuardedBy("mQuotaLock")
187     private HashMap<String, Long> mActiveAlerts = Maps.newHashMap();
188     /** Set of UIDs blacklisted on metered networks. */
189     @GuardedBy("mRulesLock")
190     private SparseBooleanArray mUidRejectOnMetered = new SparseBooleanArray();
191     /** Set of UIDs whitelisted on metered networks. */
192     @GuardedBy("mRulesLock")
193     private SparseBooleanArray mUidAllowOnMetered = new SparseBooleanArray();
194     /** Set of UIDs with cleartext penalties. */
195     @GuardedBy("mQuotaLock")
196     private SparseIntArray mUidCleartextPolicy = new SparseIntArray();
197     /** Set of UIDs that are to be blocked/allowed by firewall controller. */
198     @GuardedBy("mRulesLock")
199     private SparseIntArray mUidFirewallRules = new SparseIntArray();
200     /**
201      * Set of UIDs that are to be blocked/allowed by firewall controller.  This set of Ids matches
202      * to application idles.
203      */
204     @GuardedBy("mRulesLock")
205     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      */
210     @GuardedBy("mRulesLock")
211     private SparseIntArray mUidFirewallDozableRules = new SparseIntArray();
212     /**
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      */
216     @GuardedBy("mRulesLock")
217     private SparseIntArray mUidFirewallPowerSaveRules = new SparseIntArray();
218     /** Set of states for the child firewall chains. True if the chain is active. */
219     @GuardedBy("mRulesLock")
220     final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray();
221 
222     @GuardedBy("mQuotaLock")
223     private volatile boolean mDataSaverMode;
224 
225     private final Object mIdleTimerLock = new Object();
226     /** Set of interfaces with active idle timers. */
227     private static class IdleTimerParams {
228         public final int timeout;
229         public final int type;
230         public int networkCount;
231 
IdleTimerParams(int timeout, int type)232         IdleTimerParams(int timeout, int type) {
233             this.timeout = timeout;
234             this.type = type;
235             this.networkCount = 1;
236         }
237     }
238     private HashMap<String, IdleTimerParams> mActiveIdleTimers = Maps.newHashMap();
239 
240     private volatile boolean mFirewallEnabled;
241     private volatile boolean mStrictEnabled;
242 
243     private boolean mMobileActivityFromRadio = false;
244     private int mLastPowerStateFromRadio = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
245     private int mLastPowerStateFromWifi = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
246 
247     private final RemoteCallbackList<INetworkActivityListener> mNetworkActivityListeners =
248             new RemoteCallbackList<>();
249     private boolean mNetworkActive;
250 
251     /**
252      * Constructs a new NetworkManagementService instance
253      *
254      * @param context  Binder context for this service
255      */
NetworkManagementService( Context context, SystemServices services)256     private NetworkManagementService(
257             Context context, SystemServices services) {
258         mContext = context;
259         mServices = services;
260 
261         mDaemonHandler = new Handler(FgThread.get().getLooper());
262 
263         mNetdUnsolicitedEventListener = new NetdUnsolicitedEventListener();
264 
265         mServices.registerLocalService(new LocalService());
266 
267         synchronized (mTetheringStatsProviders) {
268             mTetheringStatsProviders.put(new NetdTetheringStatsProvider(), "netd");
269         }
270     }
271 
272     @VisibleForTesting
NetworkManagementService()273     NetworkManagementService() {
274         mContext = null;
275         mDaemonHandler = null;
276         mServices = null;
277         mNetdUnsolicitedEventListener = null;
278     }
279 
create(Context context, SystemServices services)280     static NetworkManagementService create(Context context, SystemServices services)
281             throws InterruptedException {
282         final NetworkManagementService service =
283                 new NetworkManagementService(context, services);
284         if (DBG) Slog.d(TAG, "Creating NetworkManagementService");
285         if (DBG) Slog.d(TAG, "Connecting native netd service");
286         service.connectNativeNetdService();
287         if (DBG) Slog.d(TAG, "Connected");
288         return service;
289     }
290 
create(Context context)291     public static NetworkManagementService create(Context context) throws InterruptedException {
292         return create(context, new SystemServices());
293     }
294 
systemReady()295     public void systemReady() {
296         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         }
305     }
306 
getBatteryStats()307     private IBatteryStats getBatteryStats() {
308         synchronized (this) {
309             if (mBatteryStats != null) {
310                 return mBatteryStats;
311             }
312             mBatteryStats =
313                     IBatteryStats.Stub.asInterface(mServices.getService(BatteryStats.SERVICE_NAME));
314             return mBatteryStats;
315         }
316     }
317 
318     @Override
registerObserver(INetworkManagementEventObserver observer)319     public void registerObserver(INetworkManagementEventObserver observer) {
320         NetworkStack.checkNetworkStackPermission(mContext);
321         mObservers.register(observer);
322     }
323 
324     @Override
unregisterObserver(INetworkManagementEventObserver observer)325     public void unregisterObserver(INetworkManagementEventObserver observer) {
326         NetworkStack.checkNetworkStackPermission(mContext);
327         mObservers.unregister(observer);
328     }
329 
330     @FunctionalInterface
331     private interface NetworkManagementEventCallback {
sendCallback(INetworkManagementEventObserver o)332         public void sendCallback(INetworkManagementEventObserver o) throws RemoteException;
333     }
334 
invokeForAllObservers(NetworkManagementEventCallback eventCallback)335     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) {
342                 }
343             }
344         } finally {
345             mObservers.finishBroadcast();
346         }
347     }
348 
349     /**
350      * Notify our observers of an interface status change
351      */
notifyInterfaceStatusChanged(String iface, boolean up)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      */
notifyInterfaceLinkStateChanged(String iface, boolean up)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      */
notifyInterfaceAdded(String iface)367     private void notifyInterfaceAdded(String iface) {
368         invokeForAllObservers(o -> o.interfaceAdded(iface));
369     }
370 
371     /**
372      * Notify our observers of an interface removal.
373      */
notifyInterfaceRemoved(String iface)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      */
notifyLimitReached(String limitName, String iface)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      */
notifyInterfaceClassActivity(int type, boolean isActive, long tsNanos, int uid, boolean fromRadio)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) {
414                 }
415                 FrameworkStatsLog.write_non_chained(
416                         FrameworkStatsLog.MOBILE_RADIO_POWER_STATE_CHANGED, uid, null, powerState);
417             }
418         }
419 
420         if (ConnectivityManager.isNetworkTypeWifi(type)) {
421             if (mLastPowerStateFromWifi != powerState) {
422                 mLastPowerStateFromWifi = powerState;
423                 try {
424                     getBatteryStats().noteWifiRadioPowerState(powerState, tsNanos, uid);
425                 } catch (RemoteException e) {
426                 }
427                 FrameworkStatsLog.write_non_chained(
428                         FrameworkStatsLog.WIFI_RADIO_POWER_STATE_CHANGED, uid, null, powerState);
429             }
430         }
431 
432         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));
440         }
441 
442         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();
456         }
457     }
458 
459     @Override
registerTetheringStatsProvider(ITetheringStatsProvider provider, String name)460     public void registerTetheringStatsProvider(ITetheringStatsProvider provider, String name) {
461         NetworkStack.checkNetworkStackPermission(mContext);
462         Objects.requireNonNull(provider);
463         synchronized(mTetheringStatsProviders) {
464             mTetheringStatsProviders.put(provider, name);
465         }
466     }
467 
468     @Override
unregisterTetheringStatsProvider(ITetheringStatsProvider provider)469     public void unregisterTetheringStatsProvider(ITetheringStatsProvider provider) {
470         NetworkStack.checkNetworkStackPermission(mContext);
471         synchronized(mTetheringStatsProviders) {
472             mTetheringStatsProviders.remove(provider);
473         }
474     }
475 
476     @Override
tetherLimitReached(ITetheringStatsProvider provider)477     public void tetherLimitReached(ITetheringStatsProvider provider) {
478         NetworkStack.checkNetworkStackPermission(mContext);
479         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.
484             mDaemonHandler.post(() -> notifyLimitReached(LIMIT_GLOBAL_ALERT, null));
485         }
486     }
487 
488     // Sync the state of the given chain with the native daemon.
syncFirewallChainLocked(int chain, String name)489     private void syncFirewallChainLocked(int chain, String name) {
490         SparseIntArray rules;
491         synchronized (mRulesLock) {
492             final SparseIntArray uidFirewallRules = getUidFirewallRulesLR(chain);
493             // Make a copy of the current rules, and then clear them. This is because
494             // 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();
499             uidFirewallRules.clear();
500         }
501         if (rules.size() > 0) {
502             // 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.
505             if (DBG) Slog.d(TAG, "Pushing " + rules.size() + " active firewall "
506                     + name + "UID rules");
507             for (int i = 0; i < rules.size(); i++) {
508                 setFirewallUidRuleLocked(chain, rules.keyAt(i), rules.valueAt(i));
509             }
510         }
511     }
512 
connectNativeNetdService()513     private void connectNativeNetdService() {
514         mNetdService = mServices.getNetd();
515         try {
516             mNetdService.registerUnsolicitedEventListener(mNetdUnsolicitedEventListener);
517             if (DBG) Slog.d(TAG, "Register unsolicited event listener");
518         } catch (RemoteException | ServiceSpecificException e) {
519             Slog.e(TAG, "Failed to set Netd unsolicited event listener " + e);
520         }
521     }
522 
523     /**
524      * Prepare native daemon once connected, enabling modules and pushing any
525      * existing in-memory rules.
526      */
prepareNativeDaemon()527     private void prepareNativeDaemon() {
528 
529         // push any existing quota or UID rules
530         synchronized (mQuotaLock) {
531 
532             // Netd unconditionally enable bandwidth control
533             SystemProperties.set(PROP_QTAGUID_ENABLED, "1");
534 
535             mStrictEnabled = true;
536 
537             setDataSaverModeEnabled(mDataSaverMode);
538 
539             int size = mActiveQuotas.size();
540             if (size > 0) {
541                 if (DBG) Slog.d(TAG, "Pushing " + size + " active quota rules");
542                 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) {
551                 if (DBG) Slog.d(TAG, "Pushing " + size + " active alert rules");
552                 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 
559             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) {
577                 for (int i = 0; i < uidRejectOnQuota.size(); i++) {
578                     setUidMeteredNetworkBlacklist(uidRejectOnQuota.keyAt(i),
579                             uidRejectOnQuota.valueAt(i));
580                 }
581             }
582             if (uidAcceptOnQuota != null) {
583                 for (int i = 0; i < uidAcceptOnQuota.size(); i++) {
584                     setUidMeteredNetworkWhitelist(uidAcceptOnQuota.keyAt(i),
585                             uidAcceptOnQuota.valueAt(i));
586                 }
587             }
588 
589             size = mUidCleartextPolicy.size();
590             if (size > 0) {
591                 if (DBG) Slog.d(TAG, "Pushing " + size + " active UID cleartext policies");
592                 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             }
598 
599             setFirewallEnabled(mFirewallEnabled);
600 
601             syncFirewallChainLocked(FIREWALL_CHAIN_NONE, "");
602             syncFirewallChainLocked(FIREWALL_CHAIN_STANDBY, "standby ");
603             syncFirewallChainLocked(FIREWALL_CHAIN_DOZABLE, "dozable ");
604             syncFirewallChainLocked(FIREWALL_CHAIN_POWERSAVE, "powersave ");
605 
606             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                 }
612             }
613         }
614 
615 
616         try {
617             getBatteryStats().noteNetworkStatsEnabled();
618         } catch (RemoteException e) {
619         }
620 
621     }
622 
623     /**
624      * Notify our observers of a new or updated interface address.
625      */
notifyAddressUpdated(String iface, LinkAddress address)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      */
notifyAddressRemoved(String iface, LinkAddress address)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      */
notifyInterfaceDnsServerInfo(String iface, long lifetime, String[] addresses)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      */
notifyRouteChange(boolean updated, RouteInfo route)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
onInterfaceClassActivityChanged(boolean isActive, int label, long timestamp, int uid)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
onQuotaLimitReached(String alertName, String ifName)670         public void onQuotaLimitReached(String alertName, String ifName)
671                 throws RemoteException {
672             mDaemonHandler.post(() -> notifyLimitReached(alertName, ifName));
673         }
674 
675         @Override
onInterfaceDnsServerInfo(String ifName, long lifetime, String[] servers)676         public void onInterfaceDnsServerInfo(String ifName,
677                 long lifetime, String[] servers) throws RemoteException {
678             mDaemonHandler.post(() -> notifyInterfaceDnsServerInfo(ifName, lifetime, servers));
679         }
680 
681         @Override
onInterfaceAddressUpdated(String addr, String ifName, int flags, int scope)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
onInterfaceAddressRemoved(String addr, String ifName, int flags, int scope)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
onInterfaceAdded(String ifName)696         public void onInterfaceAdded(String ifName) throws RemoteException {
697             mDaemonHandler.post(() -> notifyInterfaceAdded(ifName));
698         }
699 
700         @Override
onInterfaceRemoved(String ifName)701         public void onInterfaceRemoved(String ifName) throws RemoteException {
702             mDaemonHandler.post(() -> notifyInterfaceRemoved(ifName));
703         }
704 
705         @Override
onInterfaceChanged(String ifName, boolean up)706         public void onInterfaceChanged(String ifName, boolean up)
707                 throws RemoteException {
708             mDaemonHandler.post(() -> notifyInterfaceStatusChanged(ifName, up));
709         }
710 
711         @Override
onInterfaceLinkStateChanged(String ifName, boolean up)712         public void onInterfaceLinkStateChanged(String ifName, boolean up)
713                 throws RemoteException {
714             mDaemonHandler.post(() -> notifyInterfaceLinkStateChanged(ifName, up));
715         }
716 
717         @Override
onRouteChanged(boolean updated, String route, String gateway, String ifName)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
onStrictCleartextDetected(int uid, String hex)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         }
733 
734         @Override
getInterfaceVersion()735         public int getInterfaceVersion() {
736             return INetdUnsolicitedEventListener.VERSION;
737         }
738 
739         @Override
getInterfaceHash()740         public String getInterfaceHash() {
741             return INetdUnsolicitedEventListener.HASH;
742         }
743     }
744 
745     //
746     // INetworkManagementService members
747     //
748     @Override
listInterfaces()749     public String[] listInterfaces() {
750         // TODO: Remove CONNECTIVITY_INTERNAL after bluetooth tethering has no longer called these
751         //  APIs.
752         NetworkStack.checkNetworkStackPermissionOr(mContext, CONNECTIVITY_INTERNAL);
753         try {
754             return mNetdService.interfaceGetList();
755         } catch (RemoteException | ServiceSpecificException e) {
756             throw new IllegalStateException(e);
757         }
758     }
759 
760     /**
761      * Convert InterfaceConfiguration to InterfaceConfigurationParcel with given ifname.
762      */
toStableParcel(InterfaceConfiguration cfg, String iface)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      */
fromStableParcel(InterfaceConfigurationParcel p)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 
800     @Override
getInterfaceConfig(String iface)801     public InterfaceConfiguration getInterfaceConfig(String iface) {
802         // TODO: Remove CONNECTIVITY_INTERNAL after bluetooth tethering has no longer called these
803         //  APIs.
804         NetworkStack.checkNetworkStackPermissionOr(mContext, CONNECTIVITY_INTERNAL);
805         final InterfaceConfigurationParcel result;
806         try {
807             result = mNetdService.interfaceGetCfg(iface);
808         } catch (RemoteException | ServiceSpecificException e) {
809             throw new IllegalStateException(e);
810         }
811 
812         try {
813             final InterfaceConfiguration cfg = fromStableParcel(result);
814             return cfg;
815         } catch (IllegalArgumentException iae) {
816             throw new IllegalStateException("Invalid InterfaceConfigurationParcel", iae);
817         }
818     }
819 
820     @Override
setInterfaceConfig(String iface, InterfaceConfiguration cfg)821     public void setInterfaceConfig(String iface, InterfaceConfiguration cfg) {
822         // TODO: Remove CONNECTIVITY_INTERNAL after bluetooth tethering has no longer called these
823         //  APIs.
824         NetworkStack.checkNetworkStackPermissionOr(mContext, CONNECTIVITY_INTERNAL);
825         LinkAddress linkAddr = cfg.getLinkAddress();
826         if (linkAddr == null || linkAddr.getAddress() == null) {
827             throw new IllegalStateException("Null LinkAddress given");
828         }
829 
830         final InterfaceConfigurationParcel cfgParcel = toStableParcel(cfg, iface);
831 
832         try {
833             mNetdService.interfaceSetCfg(cfgParcel);
834         } catch (RemoteException | ServiceSpecificException e) {
835             throw new IllegalStateException(e);
836         }
837     }
838 
839     @Override
setInterfaceDown(String iface)840     public void setInterfaceDown(String iface) {
841         NetworkStack.checkNetworkStackPermission(mContext);
842         final InterfaceConfiguration ifcg = getInterfaceConfig(iface);
843         ifcg.setInterfaceDown();
844         setInterfaceConfig(iface, ifcg);
845     }
846 
847     @Override
setInterfaceUp(String iface)848     public void setInterfaceUp(String iface) {
849         NetworkStack.checkNetworkStackPermission(mContext);
850         final InterfaceConfiguration ifcg = getInterfaceConfig(iface);
851         ifcg.setInterfaceUp();
852         setInterfaceConfig(iface, ifcg);
853     }
854 
855     @Override
setInterfaceIpv6PrivacyExtensions(String iface, boolean enable)856     public void setInterfaceIpv6PrivacyExtensions(String iface, boolean enable) {
857         NetworkStack.checkNetworkStackPermission(mContext);
858         try {
859             mNetdService.interfaceSetIPv6PrivacyExtensions(iface, enable);
860         } catch (RemoteException | ServiceSpecificException e) {
861             throw new IllegalStateException(e);
862         }
863     }
864 
865     /* 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 */
867     @Override
clearInterfaceAddresses(String iface)868     public void clearInterfaceAddresses(String iface) {
869         NetworkStack.checkNetworkStackPermission(mContext);
870         try {
871             mNetdService.interfaceClearAddrs(iface);
872         } catch (RemoteException | ServiceSpecificException e) {
873             throw new IllegalStateException(e);
874         }
875     }
876 
877     @Override
enableIpv6(String iface)878     public void enableIpv6(String iface) {
879         NetworkStack.checkNetworkStackPermission(mContext);
880         try {
881             mNetdService.interfaceSetEnableIPv6(iface, true);
882         } catch (RemoteException | ServiceSpecificException e) {
883             throw new IllegalStateException(e);
884         }
885     }
886 
887     @Override
setIPv6AddrGenMode(String iface, int mode)888     public void setIPv6AddrGenMode(String iface, int mode) throws ServiceSpecificException {
889         NetworkStack.checkNetworkStackPermission(mContext);
890         try {
891             mNetdService.setIPv6AddrGenMode(iface, mode);
892         } catch (RemoteException e) {
893             throw e.rethrowAsRuntimeException();
894         }
895     }
896 
897     @Override
disableIpv6(String iface)898     public void disableIpv6(String iface) {
899         NetworkStack.checkNetworkStackPermission(mContext);
900         try {
901             mNetdService.interfaceSetEnableIPv6(iface, false);
902         } catch (RemoteException | ServiceSpecificException e) {
903             throw new IllegalStateException(e);
904         }
905     }
906 
907     @Override
addRoute(int netId, RouteInfo route)908     public void addRoute(int netId, RouteInfo route) {
909         NetworkStack.checkNetworkStackPermission(mContext);
910         RouteUtils.modifyRoute(mNetdService, ModifyOperation.ADD, netId, route);
911     }
912 
913     @Override
removeRoute(int netId, RouteInfo route)914     public void removeRoute(int netId, RouteInfo route) {
915         NetworkStack.checkNetworkStackPermission(mContext);
916         RouteUtils.modifyRoute(mNetdService, ModifyOperation.REMOVE, netId, route);
917     }
918 
readRouteList(String filename)919     private ArrayList<String> readRouteList(String filename) {
920         FileInputStream fstream = null;
921         ArrayList<String> list = new ArrayList<>();
922 
923         try {
924             fstream = new FileInputStream(filename);
925             DataInputStream in = new DataInputStream(fstream);
926             BufferedReader br = new BufferedReader(new InputStreamReader(in));
927             String s;
928 
929             // throw away the title line
930 
931             while (((s = br.readLine()) != null) && (s.length() != 0)) {
932                 list.add(s);
933             }
934         } catch (IOException ex) {
935             // return current list, possibly empty
936         } finally {
937             if (fstream != null) {
938                 try {
939                     fstream.close();
940                 } catch (IOException ex) {}
941             }
942         }
943 
944         return list;
945     }
946 
947     @Override
setMtu(String iface, int mtu)948     public void setMtu(String iface, int mtu) {
949         NetworkStack.checkNetworkStackPermission(mContext);
950 
951         try {
952             mNetdService.interfaceSetMtu(iface, mtu);
953         } catch (RemoteException | ServiceSpecificException e) {
954             throw new IllegalStateException(e);
955         }
956     }
957 
958     @Override
shutdown()959     public void shutdown() {
960         // TODO: remove from aidl if nobody calls externally
961         mContext.enforceCallingOrSelfPermission(SHUTDOWN, TAG);
962 
963         Slog.i(TAG, "Shutting down");
964     }
965 
966     @Override
getIpForwardingEnabled()967     public boolean getIpForwardingEnabled() throws IllegalStateException{
968         NetworkStack.checkNetworkStackPermission(mContext);
969 
970         try {
971             final boolean isEnabled = mNetdService.ipfwdEnabled();
972             return isEnabled;
973         } catch (RemoteException | ServiceSpecificException e) {
974             throw new IllegalStateException(e);
975         }
976     }
977 
978     @Override
setIpForwardingEnabled(boolean enable)979     public void setIpForwardingEnabled(boolean enable) {
980         NetworkStack.checkNetworkStackPermission(mContext);
981         try {
982             if (enable) {
983                 mNetdService.ipfwdEnableForwarding("tethering");
984             } else {
985                 mNetdService.ipfwdDisableForwarding("tethering");
986             }
987         } catch (RemoteException | ServiceSpecificException e) {
988             throw new IllegalStateException(e);
989         }
990     }
991 
992     @Override
startTethering(String[] dhcpRange)993     public void startTethering(String[] dhcpRange) {
994         startTetheringWithConfiguration(true, dhcpRange);
995     }
996 
997     @Override
startTetheringWithConfiguration(boolean usingLegacyDnsProxy, String[] dhcpRange)998     public void startTetheringWithConfiguration(boolean usingLegacyDnsProxy, String[] dhcpRange) {
999         NetworkStack.checkNetworkStackPermission(mContext);
1000         try {
1001             NetdUtils.tetherStart(mNetdService, usingLegacyDnsProxy, dhcpRange);
1002         } catch (RemoteException | ServiceSpecificException e) {
1003             throw new IllegalStateException(e);
1004         }
1005     }
1006 
1007     @Override
stopTethering()1008     public void stopTethering() {
1009         NetworkStack.checkNetworkStackPermission(mContext);
1010         try {
1011             mNetdService.tetherStop();
1012         } catch (RemoteException | ServiceSpecificException e) {
1013             throw new IllegalStateException(e);
1014         }
1015     }
1016 
1017     @Override
isTetheringStarted()1018     public boolean isTetheringStarted() {
1019         NetworkStack.checkNetworkStackPermission(mContext);
1020 
1021         try {
1022             final boolean isEnabled = mNetdService.tetherIsEnabled();
1023             return isEnabled;
1024         } catch (RemoteException | ServiceSpecificException e) {
1025             throw new IllegalStateException(e);
1026         }
1027     }
1028 
1029     @Override
tetherInterface(String iface)1030     public void tetherInterface(String iface) {
1031         NetworkStack.checkNetworkStackPermission(mContext);
1032         try {
1033             final LinkAddress addr = getInterfaceConfig(iface).getLinkAddress();
1034             final IpPrefix dest = new IpPrefix(addr.getAddress(), addr.getPrefixLength());
1035             NetdUtils.tetherInterface(mNetdService, iface, dest);
1036         } catch (RemoteException | ServiceSpecificException e) {
1037             throw new IllegalStateException(e);
1038         }
1039     }
1040 
1041     @Override
untetherInterface(String iface)1042     public void untetherInterface(String iface) {
1043         NetworkStack.checkNetworkStackPermission(mContext);
1044         try {
1045             NetdUtils.untetherInterface(mNetdService, iface);
1046         } catch (RemoteException | ServiceSpecificException e) {
1047             throw new IllegalStateException(e);
1048         }
1049     }
1050 
1051     @Override
listTetheredInterfaces()1052     public String[] listTetheredInterfaces() {
1053         NetworkStack.checkNetworkStackPermission(mContext);
1054         try {
1055             return mNetdService.tetherInterfaceList();
1056         } catch (RemoteException | ServiceSpecificException e) {
1057             throw new IllegalStateException(e);
1058         }
1059     }
1060 
1061     @Override
setDnsForwarders(Network network, String[] dns)1062     public void setDnsForwarders(Network network, String[] dns) {
1063         NetworkStack.checkNetworkStackPermission(mContext);
1064 
1065         int netId = (network != null) ? network.netId : ConnectivityManager.NETID_UNSET;
1066 
1067         try {
1068             mNetdService.tetherDnsSet(netId, dns);
1069         } catch (RemoteException | ServiceSpecificException e) {
1070             throw new IllegalStateException(e);
1071         }
1072     }
1073 
1074     @Override
getDnsForwarders()1075     public String[] getDnsForwarders() {
1076         NetworkStack.checkNetworkStackPermission(mContext);
1077         try {
1078             return mNetdService.tetherDnsList();
1079         } catch (RemoteException | ServiceSpecificException e) {
1080             throw new IllegalStateException(e);
1081         }
1082     }
1083 
excludeLinkLocal(List<InterfaceAddress> addresses)1084     private List<InterfaceAddress> excludeLinkLocal(List<InterfaceAddress> addresses) {
1085         ArrayList<InterfaceAddress> filtered = new ArrayList<>(addresses.size());
1086         for (InterfaceAddress ia : addresses) {
1087             if (!ia.getAddress().isLinkLocalAddress())
1088                 filtered.add(ia);
1089         }
1090         return filtered;
1091     }
1092 
modifyInterfaceForward(boolean add, String fromIface, String toIface)1093     private void modifyInterfaceForward(boolean add, String fromIface, String toIface) {
1094         try {
1095             if (add) {
1096                 mNetdService.ipfwdAddInterfaceForward(fromIface, toIface);
1097             } else {
1098                 mNetdService.ipfwdRemoveInterfaceForward(fromIface, toIface);
1099             }
1100         } catch (RemoteException | ServiceSpecificException e) {
1101             throw new IllegalStateException(e);
1102         }
1103     }
1104 
1105     @Override
startInterfaceForwarding(String fromIface, String toIface)1106     public void startInterfaceForwarding(String fromIface, String toIface) {
1107         NetworkStack.checkNetworkStackPermission(mContext);
1108         modifyInterfaceForward(true, fromIface, toIface);
1109     }
1110 
1111     @Override
stopInterfaceForwarding(String fromIface, String toIface)1112     public void stopInterfaceForwarding(String fromIface, String toIface) {
1113         NetworkStack.checkNetworkStackPermission(mContext);
1114         modifyInterfaceForward(false, fromIface, toIface);
1115     }
1116 
1117     @Override
enableNat(String internalInterface, String externalInterface)1118     public void enableNat(String internalInterface, String externalInterface) {
1119         NetworkStack.checkNetworkStackPermission(mContext);
1120         try {
1121             mNetdService.tetherAddForward(internalInterface, externalInterface);
1122         } catch (RemoteException | ServiceSpecificException e) {
1123             throw new IllegalStateException(e);
1124         }
1125     }
1126 
1127     @Override
disableNat(String internalInterface, String externalInterface)1128     public void disableNat(String internalInterface, String externalInterface) {
1129         NetworkStack.checkNetworkStackPermission(mContext);
1130         try {
1131             mNetdService.tetherRemoveForward(internalInterface, externalInterface);
1132         } catch (RemoteException | ServiceSpecificException e) {
1133             throw new IllegalStateException(e);
1134         }
1135     }
1136 
1137     @Override
addIdleTimer(String iface, int timeout, final int type)1138     public void addIdleTimer(String iface, int timeout, final int type) {
1139         NetworkStack.checkNetworkStackPermission(mContext);
1140 
1141         if (DBG) Slog.d(TAG, "Adding idletimer");
1142 
1143         synchronized (mIdleTimerLock) {
1144             IdleTimerParams params = mActiveIdleTimers.get(iface);
1145             if (params != null) {
1146                 // the interface already has idletimer, update network count
1147                 params.networkCount++;
1148                 return;
1149             }
1150 
1151             try {
1152                 mNetdService.idletimerAddInterface(iface, timeout, Integer.toString(type));
1153             } catch (RemoteException | ServiceSpecificException e) {
1154                 throw new IllegalStateException(e);
1155             }
1156             mActiveIdleTimers.put(iface, new IdleTimerParams(timeout, type));
1157 
1158             // Networks start up.
1159             if (ConnectivityManager.isNetworkTypeMobile(type)) {
1160                 mNetworkActive = false;
1161             }
1162             mDaemonHandler.post(() -> notifyInterfaceClassActivity(type, true,
1163                     SystemClock.elapsedRealtimeNanos(), -1, false));
1164         }
1165     }
1166 
1167     @Override
removeIdleTimer(String iface)1168     public void removeIdleTimer(String iface) {
1169         NetworkStack.checkNetworkStackPermission(mContext);
1170 
1171         if (DBG) Slog.d(TAG, "Removing idletimer");
1172 
1173         synchronized (mIdleTimerLock) {
1174             final IdleTimerParams params = mActiveIdleTimers.get(iface);
1175             if (params == null || --(params.networkCount) > 0) {
1176                 return;
1177             }
1178 
1179             try {
1180                 mNetdService.idletimerRemoveInterface(iface,
1181                         params.timeout, Integer.toString(params.type));
1182             } catch (RemoteException | ServiceSpecificException e) {
1183                 throw new IllegalStateException(e);
1184             }
1185             mActiveIdleTimers.remove(iface);
1186             mDaemonHandler.post(() -> notifyInterfaceClassActivity(params.type, false,
1187                     SystemClock.elapsedRealtimeNanos(), -1, false));
1188         }
1189     }
1190 
1191     @Override
setInterfaceQuota(String iface, long quotaBytes)1192     public void setInterfaceQuota(String iface, long quotaBytes) {
1193         NetworkStack.checkNetworkStackPermission(mContext);
1194 
1195         synchronized (mQuotaLock) {
1196             if (mActiveQuotas.containsKey(iface)) {
1197                 throw new IllegalStateException("iface " + iface + " already has quota");
1198             }
1199 
1200             try {
1201                 // TODO: support quota shared across interfaces
1202                 mNetdService.bandwidthSetInterfaceQuota(iface, quotaBytes);
1203 
1204                 mActiveQuotas.put(iface, quotaBytes);
1205             } catch (RemoteException | ServiceSpecificException e) {
1206                 throw new IllegalStateException(e);
1207             }
1208 
1209             synchronized (mTetheringStatsProviders) {
1210                 for (ITetheringStatsProvider provider : mTetheringStatsProviders.keySet()) {
1211                     try {
1212                         provider.setInterfaceQuota(iface, quotaBytes);
1213                     } catch (RemoteException e) {
1214                         Log.e(TAG, "Problem setting tethering data limit on provider " +
1215                                 mTetheringStatsProviders.get(provider) + ": " + e);
1216                     }
1217                 }
1218             }
1219         }
1220     }
1221 
1222     @Override
removeInterfaceQuota(String iface)1223     public void removeInterfaceQuota(String iface) {
1224         NetworkStack.checkNetworkStackPermission(mContext);
1225 
1226         synchronized (mQuotaLock) {
1227             if (!mActiveQuotas.containsKey(iface)) {
1228                 // TODO: eventually consider throwing
1229                 return;
1230             }
1231 
1232             mActiveQuotas.remove(iface);
1233             mActiveAlerts.remove(iface);
1234 
1235             try {
1236                 // TODO: support quota shared across interfaces
1237                 mNetdService.bandwidthRemoveInterfaceQuota(iface);
1238             } catch (RemoteException | ServiceSpecificException e) {
1239                 throw new IllegalStateException(e);
1240             }
1241 
1242             synchronized (mTetheringStatsProviders) {
1243                 for (ITetheringStatsProvider provider : mTetheringStatsProviders.keySet()) {
1244                     try {
1245                         provider.setInterfaceQuota(iface, ITetheringStatsProvider.QUOTA_UNLIMITED);
1246                     } catch (RemoteException e) {
1247                         Log.e(TAG, "Problem removing tethering data limit on provider " +
1248                                 mTetheringStatsProviders.get(provider) + ": " + e);
1249                     }
1250                 }
1251             }
1252         }
1253     }
1254 
1255     @Override
setInterfaceAlert(String iface, long alertBytes)1256     public void setInterfaceAlert(String iface, long alertBytes) {
1257         NetworkStack.checkNetworkStackPermission(mContext);
1258 
1259         // quick sanity check
1260         if (!mActiveQuotas.containsKey(iface)) {
1261             throw new IllegalStateException("setting alert requires existing quota on iface");
1262         }
1263 
1264         synchronized (mQuotaLock) {
1265             if (mActiveAlerts.containsKey(iface)) {
1266                 throw new IllegalStateException("iface " + iface + " already has alert");
1267             }
1268 
1269             try {
1270                 // TODO: support alert shared across interfaces
1271                 mNetdService.bandwidthSetInterfaceAlert(iface, alertBytes);
1272                 mActiveAlerts.put(iface, alertBytes);
1273             } catch (RemoteException | ServiceSpecificException e) {
1274                 throw new IllegalStateException(e);
1275             }
1276         }
1277     }
1278 
1279     @Override
removeInterfaceAlert(String iface)1280     public void removeInterfaceAlert(String iface) {
1281         NetworkStack.checkNetworkStackPermission(mContext);
1282 
1283         synchronized (mQuotaLock) {
1284             if (!mActiveAlerts.containsKey(iface)) {
1285                 // TODO: eventually consider throwing
1286                 return;
1287             }
1288 
1289             try {
1290                 // TODO: support alert shared across interfaces
1291                 mNetdService.bandwidthRemoveInterfaceAlert(iface);
1292                 mActiveAlerts.remove(iface);
1293             } catch (RemoteException | ServiceSpecificException e) {
1294                 throw new IllegalStateException(e);
1295             }
1296         }
1297     }
1298 
1299     @Override
setGlobalAlert(long alertBytes)1300     public void setGlobalAlert(long alertBytes) {
1301         NetworkStack.checkNetworkStackPermission(mContext);
1302 
1303         try {
1304             mNetdService.bandwidthSetGlobalAlert(alertBytes);
1305         } catch (RemoteException | ServiceSpecificException e) {
1306             throw new IllegalStateException(e);
1307         }
1308     }
1309 
setUidOnMeteredNetworkList(int uid, boolean blacklist, boolean enable)1310     private void setUidOnMeteredNetworkList(int uid, boolean blacklist, boolean enable) {
1311         NetworkStack.checkNetworkStackPermission(mContext);
1312 
1313         synchronized (mQuotaLock) {
1314             boolean oldEnable;
1315             SparseBooleanArray quotaList;
1316             synchronized (mRulesLock) {
1317                 quotaList = blacklist ? mUidRejectOnMetered : mUidAllowOnMetered;
1318                 oldEnable = quotaList.get(uid, false);
1319             }
1320             if (oldEnable == enable) {
1321                 // TODO: eventually consider throwing
1322                 return;
1323             }
1324 
1325             Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "inetd bandwidth");
1326             try {
1327                 if (blacklist) {
1328                     if (enable) {
1329                         mNetdService.bandwidthAddNaughtyApp(uid);
1330                     } else {
1331                         mNetdService.bandwidthRemoveNaughtyApp(uid);
1332                     }
1333                 } else {
1334                     if (enable) {
1335                         mNetdService.bandwidthAddNiceApp(uid);
1336                     } else {
1337                         mNetdService.bandwidthRemoveNiceApp(uid);
1338                     }
1339                 }
1340                 synchronized (mRulesLock) {
1341                     if (enable) {
1342                         quotaList.put(uid, true);
1343                     } else {
1344                         quotaList.delete(uid);
1345                     }
1346                 }
1347             } catch (RemoteException | ServiceSpecificException e) {
1348                 throw new IllegalStateException(e);
1349             } finally {
1350                 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
1351             }
1352         }
1353     }
1354 
1355     @Override
setUidMeteredNetworkBlacklist(int uid, boolean enable)1356     public void setUidMeteredNetworkBlacklist(int uid, boolean enable) {
1357         setUidOnMeteredNetworkList(uid, true, enable);
1358     }
1359 
1360     @Override
setUidMeteredNetworkWhitelist(int uid, boolean enable)1361     public void setUidMeteredNetworkWhitelist(int uid, boolean enable) {
1362         setUidOnMeteredNetworkList(uid, false, enable);
1363     }
1364 
1365     @Override
setDataSaverModeEnabled(boolean enable)1366     public boolean setDataSaverModeEnabled(boolean enable) {
1367         mContext.enforceCallingOrSelfPermission(NETWORK_SETTINGS, TAG);
1368 
1369         if (DBG) Log.d(TAG, "setDataSaverMode: " + enable);
1370         synchronized (mQuotaLock) {
1371             if (mDataSaverMode == enable) {
1372                 Log.w(TAG, "setDataSaverMode(): already " + mDataSaverMode);
1373                 return true;
1374             }
1375             Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "bandwidthEnableDataSaver");
1376             try {
1377                 final boolean changed = mNetdService.bandwidthEnableDataSaver(enable);
1378                 if (changed) {
1379                     mDataSaverMode = enable;
1380                 } else {
1381                     Log.w(TAG, "setDataSaverMode(" + enable + "): netd command silently failed");
1382                 }
1383                 return changed;
1384             } catch (RemoteException e) {
1385                 Log.w(TAG, "setDataSaverMode(" + enable + "): netd command failed", e);
1386                 return false;
1387             } finally {
1388                 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
1389             }
1390         }
1391     }
1392 
makeUidRangeParcel(int start, int stop)1393     private static UidRangeParcel makeUidRangeParcel(int start, int stop) {
1394         UidRangeParcel range = new UidRangeParcel();
1395         range.start = start;
1396         range.stop = stop;
1397         return range;
1398     }
1399 
toStableParcels(UidRange[] ranges)1400     private static UidRangeParcel[] toStableParcels(UidRange[] ranges) {
1401         UidRangeParcel[] stableRanges = new UidRangeParcel[ranges.length];
1402         for (int i = 0; i < ranges.length; i++) {
1403             stableRanges[i] = makeUidRangeParcel(ranges[i].start, ranges[i].stop);
1404         }
1405         return stableRanges;
1406     }
1407 
1408     @Override
setAllowOnlyVpnForUids(boolean add, UidRange[] uidRanges)1409     public void setAllowOnlyVpnForUids(boolean add, UidRange[] uidRanges)
1410             throws ServiceSpecificException {
1411         NetworkStack.checkNetworkStackPermission(mContext);
1412         try {
1413             mNetdService.networkRejectNonSecureVpn(add, toStableParcels(uidRanges));
1414         } catch (ServiceSpecificException e) {
1415             Log.w(TAG, "setAllowOnlyVpnForUids(" + add + ", " + Arrays.toString(uidRanges) + ")"
1416                     + ": netd command failed", e);
1417             throw e;
1418         } catch (RemoteException e) {
1419             Log.w(TAG, "setAllowOnlyVpnForUids(" + add + ", " + Arrays.toString(uidRanges) + ")"
1420                     + ": netd command failed", e);
1421             throw e.rethrowAsRuntimeException();
1422         }
1423     }
1424 
applyUidCleartextNetworkPolicy(int uid, int policy)1425     private void applyUidCleartextNetworkPolicy(int uid, int policy) {
1426         final int policyValue;
1427         switch (policy) {
1428             case StrictMode.NETWORK_POLICY_ACCEPT:
1429                 policyValue = INetd.PENALTY_POLICY_ACCEPT;
1430                 break;
1431             case StrictMode.NETWORK_POLICY_LOG:
1432                 policyValue = INetd.PENALTY_POLICY_LOG;
1433                 break;
1434             case StrictMode.NETWORK_POLICY_REJECT:
1435                 policyValue = INetd.PENALTY_POLICY_REJECT;
1436                 break;
1437             default:
1438                 throw new IllegalArgumentException("Unknown policy " + policy);
1439         }
1440 
1441         try {
1442             mNetdService.strictUidCleartextPenalty(uid, policyValue);
1443             mUidCleartextPolicy.put(uid, policy);
1444         } catch (RemoteException | ServiceSpecificException e) {
1445             throw new IllegalStateException(e);
1446         }
1447     }
1448 
1449     @Override
setUidCleartextNetworkPolicy(int uid, int policy)1450     public void setUidCleartextNetworkPolicy(int uid, int policy) {
1451         if (Binder.getCallingUid() != uid) {
1452             NetworkStack.checkNetworkStackPermission(mContext);
1453         }
1454 
1455         synchronized (mQuotaLock) {
1456             final int oldPolicy = mUidCleartextPolicy.get(uid, StrictMode.NETWORK_POLICY_ACCEPT);
1457             if (oldPolicy == policy) {
1458                 // This also ensures we won't needlessly apply an ACCEPT policy if we've just
1459                 // enabled strict and the underlying iptables rules are empty.
1460                 return;
1461             }
1462 
1463             // TODO: remove this code after removing prepareNativeDaemon()
1464             if (!mStrictEnabled) {
1465                 // Module isn't enabled yet; stash the requested policy away to
1466                 // apply later once the daemon is connected.
1467                 mUidCleartextPolicy.put(uid, policy);
1468                 return;
1469             }
1470 
1471             // netd does not keep state on strict mode policies, and cannot replace a non-accept
1472             // policy without deleting it first. Rather than add state to netd, just always send
1473             // it an accept policy when switching between two non-accept policies.
1474             // TODO: consider keeping state in netd so we can simplify this code.
1475             if (oldPolicy != StrictMode.NETWORK_POLICY_ACCEPT &&
1476                     policy != StrictMode.NETWORK_POLICY_ACCEPT) {
1477                 applyUidCleartextNetworkPolicy(uid, StrictMode.NETWORK_POLICY_ACCEPT);
1478             }
1479 
1480             applyUidCleartextNetworkPolicy(uid, policy);
1481         }
1482     }
1483 
1484     @Override
isBandwidthControlEnabled()1485     public boolean isBandwidthControlEnabled() {
1486         return true;
1487     }
1488 
1489     private class NetdTetheringStatsProvider extends ITetheringStatsProvider.Stub {
1490         @Override
getTetherStats(int how)1491         public NetworkStats getTetherStats(int how) {
1492             // We only need to return per-UID stats. Per-device stats are already counted by
1493             // interface counters.
1494             if (how != STATS_PER_UID) {
1495                 return new NetworkStats(SystemClock.elapsedRealtime(), 0);
1496             }
1497 
1498             final TetherStatsParcel[] tetherStatsVec;
1499             try {
1500                 tetherStatsVec = mNetdService.tetherGetStats();
1501             } catch (RemoteException | ServiceSpecificException e) {
1502                 throw new IllegalStateException("problem parsing tethering stats: ", e);
1503             }
1504 
1505             final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(),
1506                 tetherStatsVec.length);
1507             final NetworkStats.Entry entry = new NetworkStats.Entry();
1508 
1509             for (TetherStatsParcel tetherStats : tetherStatsVec) {
1510                 try {
1511                     entry.iface = tetherStats.iface;
1512                     entry.uid = UID_TETHERING;
1513                     entry.set = SET_DEFAULT;
1514                     entry.tag = TAG_NONE;
1515                     entry.rxBytes   = tetherStats.rxBytes;
1516                     entry.rxPackets = tetherStats.rxPackets;
1517                     entry.txBytes   = tetherStats.txBytes;
1518                     entry.txPackets = tetherStats.txPackets;
1519                     stats.combineValues(entry);
1520                 } catch (ArrayIndexOutOfBoundsException e) {
1521                     throw new IllegalStateException("invalid tethering stats " + e);
1522                 }
1523             }
1524 
1525             return stats;
1526         }
1527 
1528         @Override
setInterfaceQuota(String iface, long quotaBytes)1529         public void setInterfaceQuota(String iface, long quotaBytes) {
1530             // Do nothing. netd is already informed of quota changes in setInterfaceQuota.
1531         }
1532     }
1533 
1534     @Override
getNetworkStatsTethering(int how)1535     public NetworkStats getNetworkStatsTethering(int how) {
1536         NetworkStack.checkNetworkStackPermission(mContext);
1537 
1538         final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1);
1539         synchronized (mTetheringStatsProviders) {
1540             for (ITetheringStatsProvider provider: mTetheringStatsProviders.keySet()) {
1541                 try {
1542                     stats.combineAllValues(provider.getTetherStats(how));
1543                 } catch (RemoteException e) {
1544                     Log.e(TAG, "Problem reading tethering stats from " +
1545                             mTetheringStatsProviders.get(provider) + ": " + e);
1546                 }
1547             }
1548         }
1549         return stats;
1550     }
1551 
1552     @Override
addVpnUidRanges(int netId, UidRange[] ranges)1553     public void addVpnUidRanges(int netId, UidRange[] ranges) {
1554         NetworkStack.checkNetworkStackPermission(mContext);
1555 
1556         try {
1557             mNetdService.networkAddUidRanges(netId, toStableParcels(ranges));
1558         } catch (RemoteException | ServiceSpecificException e) {
1559             throw new IllegalStateException(e);
1560         }
1561     }
1562 
1563     @Override
removeVpnUidRanges(int netId, UidRange[] ranges)1564     public void removeVpnUidRanges(int netId, UidRange[] ranges) {
1565         NetworkStack.checkNetworkStackPermission(mContext);
1566         try {
1567             mNetdService.networkRemoveUidRanges(netId, toStableParcels(ranges));
1568         } catch (RemoteException | ServiceSpecificException e) {
1569             throw new IllegalStateException(e);
1570         }
1571     }
1572 
1573     @Override
setFirewallEnabled(boolean enabled)1574     public void setFirewallEnabled(boolean enabled) {
1575         enforceSystemUid();
1576         try {
1577             mNetdService.firewallSetFirewallType(
1578                     enabled ? INetd.FIREWALL_WHITELIST : INetd.FIREWALL_BLACKLIST);
1579             mFirewallEnabled = enabled;
1580         } catch (RemoteException | ServiceSpecificException e) {
1581             throw new IllegalStateException(e);
1582         }
1583     }
1584 
1585     @Override
isFirewallEnabled()1586     public boolean isFirewallEnabled() {
1587         enforceSystemUid();
1588         return mFirewallEnabled;
1589     }
1590 
1591     @Override
setFirewallInterfaceRule(String iface, boolean allow)1592     public void setFirewallInterfaceRule(String iface, boolean allow) {
1593         enforceSystemUid();
1594         Preconditions.checkState(mFirewallEnabled);
1595         try {
1596             mNetdService.firewallSetInterfaceRule(iface,
1597                     allow ? INetd.FIREWALL_RULE_ALLOW : INetd.FIREWALL_RULE_DENY);
1598         } catch (RemoteException | ServiceSpecificException e) {
1599             throw new IllegalStateException(e);
1600         }
1601     }
1602 
closeSocketsForFirewallChainLocked(int chain, String chainName)1603     private void closeSocketsForFirewallChainLocked(int chain, String chainName) {
1604         // UID ranges to close sockets on.
1605         UidRangeParcel[] ranges;
1606         // UID ranges whose sockets we won't touch.
1607         int[] exemptUids;
1608 
1609         int numUids = 0;
1610         if (DBG) Slog.d(TAG, "Closing sockets after enabling chain " + chainName);
1611         if (getFirewallType(chain) == FIREWALL_WHITELIST) {
1612             // Close all sockets on all non-system UIDs...
1613             ranges = new UidRangeParcel[] {
1614                 // TODO: is there a better way of finding all existing users? If so, we could
1615                 // specify their ranges here.
1616                 makeUidRangeParcel(Process.FIRST_APPLICATION_UID, Integer.MAX_VALUE),
1617             };
1618             // ... except for the UIDs that have allow rules.
1619             synchronized (mRulesLock) {
1620                 final SparseIntArray rules = getUidFirewallRulesLR(chain);
1621                 exemptUids = new int[rules.size()];
1622                 for (int i = 0; i < exemptUids.length; i++) {
1623                     if (rules.valueAt(i) == FIREWALL_RULE_ALLOW) {
1624                         exemptUids[numUids] = rules.keyAt(i);
1625                         numUids++;
1626                     }
1627                 }
1628             }
1629             // Normally, whitelist chains only contain deny rules, so numUids == exemptUids.length.
1630             // But the code does not guarantee this in any way, and at least in one case - if we add
1631             // a UID rule to the firewall, and then disable the firewall - the chains can contain
1632             // the wrong type of rule. In this case, don't close connections that we shouldn't.
1633             //
1634             // TODO: tighten up this code by ensuring we never set the wrong type of rule, and
1635             // fix setFirewallEnabled to grab mQuotaLock and clear rules.
1636             if (numUids != exemptUids.length) {
1637                 exemptUids = Arrays.copyOf(exemptUids, numUids);
1638             }
1639         } else {
1640             // Close sockets for every UID that has a deny rule...
1641             synchronized (mRulesLock) {
1642                 final SparseIntArray rules = getUidFirewallRulesLR(chain);
1643                 ranges = new UidRangeParcel[rules.size()];
1644                 for (int i = 0; i < ranges.length; i++) {
1645                     if (rules.valueAt(i) == FIREWALL_RULE_DENY) {
1646                         int uid = rules.keyAt(i);
1647                         ranges[numUids] = makeUidRangeParcel(uid, uid);
1648                         numUids++;
1649                     }
1650                 }
1651             }
1652             // As above; usually numUids == ranges.length, but not always.
1653             if (numUids != ranges.length) {
1654                 ranges = Arrays.copyOf(ranges, numUids);
1655             }
1656             // ... with no exceptions.
1657             exemptUids = new int[0];
1658         }
1659 
1660         try {
1661             mNetdService.socketDestroy(ranges, exemptUids);
1662         } catch(RemoteException | ServiceSpecificException e) {
1663             Slog.e(TAG, "Error closing sockets after enabling chain " + chainName + ": " + e);
1664         }
1665     }
1666 
1667     @Override
setFirewallChainEnabled(int chain, boolean enable)1668     public void setFirewallChainEnabled(int chain, boolean enable) {
1669         enforceSystemUid();
1670         synchronized (mQuotaLock) {
1671             synchronized (mRulesLock) {
1672                 if (getFirewallChainState(chain) == enable) {
1673                     // All is the same, nothing to do.  This relies on the fact that netd has child
1674                     // chains default detached.
1675                     return;
1676                 }
1677                 setFirewallChainState(chain, enable);
1678             }
1679 
1680             final String chainName = getFirewallChainName(chain);
1681             if (chain == FIREWALL_CHAIN_NONE) {
1682                 throw new IllegalArgumentException("Bad child chain: " + chainName);
1683             }
1684 
1685             try {
1686                 mNetdService.firewallEnableChildChain(chain, enable);
1687             } catch (RemoteException | ServiceSpecificException e) {
1688                 throw new IllegalStateException(e);
1689             }
1690 
1691             // Close any sockets that were opened by the affected UIDs. This has to be done after
1692             // disabling network connectivity, in case they react to the socket close by reopening
1693             // the connection and race with the iptables commands that enable the firewall. All
1694             // whitelist and blacklist chains allow RSTs through.
1695             if (enable) {
1696                 closeSocketsForFirewallChainLocked(chain, chainName);
1697             }
1698         }
1699     }
1700 
getFirewallChainName(int chain)1701     private String getFirewallChainName(int chain) {
1702         switch (chain) {
1703             case FIREWALL_CHAIN_STANDBY:
1704                 return FIREWALL_CHAIN_NAME_STANDBY;
1705             case FIREWALL_CHAIN_DOZABLE:
1706                 return FIREWALL_CHAIN_NAME_DOZABLE;
1707             case FIREWALL_CHAIN_POWERSAVE:
1708                 return FIREWALL_CHAIN_NAME_POWERSAVE;
1709             default:
1710                 throw new IllegalArgumentException("Bad child chain: " + chain);
1711         }
1712     }
1713 
getFirewallType(int chain)1714     private int getFirewallType(int chain) {
1715         switch (chain) {
1716             case FIREWALL_CHAIN_STANDBY:
1717                 return FIREWALL_BLACKLIST;
1718             case FIREWALL_CHAIN_DOZABLE:
1719                 return FIREWALL_WHITELIST;
1720             case FIREWALL_CHAIN_POWERSAVE:
1721                 return FIREWALL_WHITELIST;
1722             default:
1723                 return isFirewallEnabled() ? FIREWALL_WHITELIST : FIREWALL_BLACKLIST;
1724         }
1725     }
1726 
1727     @Override
setFirewallUidRules(int chain, int[] uids, int[] rules)1728     public void setFirewallUidRules(int chain, int[] uids, int[] rules) {
1729         enforceSystemUid();
1730         synchronized (mQuotaLock) {
1731             synchronized (mRulesLock) {
1732                 SparseIntArray uidFirewallRules = getUidFirewallRulesLR(chain);
1733                 SparseIntArray newRules = new SparseIntArray();
1734                 // apply new set of rules
1735                 for (int index = uids.length - 1; index >= 0; --index) {
1736                     int uid = uids[index];
1737                     int rule = rules[index];
1738                     updateFirewallUidRuleLocked(chain, uid, rule);
1739                     newRules.put(uid, rule);
1740                 }
1741                 // collect the rules to remove.
1742                 SparseIntArray rulesToRemove = new SparseIntArray();
1743                 for (int index = uidFirewallRules.size() - 1; index >= 0; --index) {
1744                     int uid = uidFirewallRules.keyAt(index);
1745                     if (newRules.indexOfKey(uid) < 0) {
1746                         rulesToRemove.put(uid, FIREWALL_RULE_DEFAULT);
1747                     }
1748                 }
1749                 // remove dead rules
1750                 for (int index = rulesToRemove.size() - 1; index >= 0; --index) {
1751                     int uid = rulesToRemove.keyAt(index);
1752                     updateFirewallUidRuleLocked(chain, uid, FIREWALL_RULE_DEFAULT);
1753                 }
1754             }
1755             try {
1756                 switch (chain) {
1757                     case FIREWALL_CHAIN_DOZABLE:
1758                         mNetdService.firewallReplaceUidChain("fw_dozable", true, uids);
1759                         break;
1760                     case FIREWALL_CHAIN_STANDBY:
1761                         mNetdService.firewallReplaceUidChain("fw_standby", false, uids);
1762                         break;
1763                     case FIREWALL_CHAIN_POWERSAVE:
1764                         mNetdService.firewallReplaceUidChain("fw_powersave", true, uids);
1765                         break;
1766                     case FIREWALL_CHAIN_NONE:
1767                     default:
1768                         Slog.d(TAG, "setFirewallUidRules() called on invalid chain: " + chain);
1769                 }
1770             } catch (RemoteException e) {
1771                 Slog.w(TAG, "Error flushing firewall chain " + chain, e);
1772             }
1773         }
1774     }
1775 
1776     @Override
setFirewallUidRule(int chain, int uid, int rule)1777     public void setFirewallUidRule(int chain, int uid, int rule) {
1778         enforceSystemUid();
1779         synchronized (mQuotaLock) {
1780             setFirewallUidRuleLocked(chain, uid, rule);
1781         }
1782     }
1783 
setFirewallUidRuleLocked(int chain, int uid, int rule)1784     private void setFirewallUidRuleLocked(int chain, int uid, int rule) {
1785         if (updateFirewallUidRuleLocked(chain, uid, rule)) {
1786             final int ruleType = getFirewallRuleType(chain, rule);
1787             try {
1788                 mNetdService.firewallSetUidRule(chain, uid, ruleType);
1789             } catch (RemoteException | ServiceSpecificException e) {
1790                 throw new IllegalStateException(e);
1791             }
1792         }
1793     }
1794 
1795     // TODO: now that netd supports batching, NMS should not keep these data structures anymore...
updateFirewallUidRuleLocked(int chain, int uid, int rule)1796     private boolean updateFirewallUidRuleLocked(int chain, int uid, int rule) {
1797         synchronized (mRulesLock) {
1798             SparseIntArray uidFirewallRules = getUidFirewallRulesLR(chain);
1799 
1800             final int oldUidFirewallRule = uidFirewallRules.get(uid, FIREWALL_RULE_DEFAULT);
1801             if (DBG) {
1802                 Slog.d(TAG, "oldRule = " + oldUidFirewallRule
1803                         + ", newRule=" + rule + " for uid=" + uid + " on chain " + chain);
1804             }
1805             if (oldUidFirewallRule == rule) {
1806                 if (DBG) Slog.d(TAG, "!!!!! Skipping change");
1807                 // TODO: eventually consider throwing
1808                 return false;
1809             }
1810 
1811             String ruleName = getFirewallRuleName(chain, rule);
1812             String oldRuleName = getFirewallRuleName(chain, oldUidFirewallRule);
1813 
1814             if (rule == NetworkPolicyManager.FIREWALL_RULE_DEFAULT) {
1815                 uidFirewallRules.delete(uid);
1816             } else {
1817                 uidFirewallRules.put(uid, rule);
1818             }
1819             return !ruleName.equals(oldRuleName);
1820         }
1821     }
1822 
getFirewallRuleName(int chain, int rule)1823     private @NonNull String getFirewallRuleName(int chain, int rule) {
1824         String ruleName;
1825         if (getFirewallType(chain) == FIREWALL_WHITELIST) {
1826             if (rule == FIREWALL_RULE_ALLOW) {
1827                 ruleName = "allow";
1828             } else {
1829                 ruleName = "deny";
1830             }
1831         } else { // Blacklist mode
1832             if (rule == FIREWALL_RULE_DENY) {
1833                 ruleName = "deny";
1834             } else {
1835                 ruleName = "allow";
1836             }
1837         }
1838         return ruleName;
1839     }
1840 
1841     @GuardedBy("mRulesLock")
getUidFirewallRulesLR(int chain)1842     private @NonNull SparseIntArray getUidFirewallRulesLR(int chain) {
1843         switch (chain) {
1844             case FIREWALL_CHAIN_STANDBY:
1845                 return mUidFirewallStandbyRules;
1846             case FIREWALL_CHAIN_DOZABLE:
1847                 return mUidFirewallDozableRules;
1848             case FIREWALL_CHAIN_POWERSAVE:
1849                 return mUidFirewallPowerSaveRules;
1850             case FIREWALL_CHAIN_NONE:
1851                 return mUidFirewallRules;
1852             default:
1853                 throw new IllegalArgumentException("Unknown chain:" + chain);
1854         }
1855     }
1856 
getFirewallRuleType(int chain, int rule)1857     private int getFirewallRuleType(int chain, int rule) {
1858         if (rule == NetworkPolicyManager.FIREWALL_RULE_DEFAULT) {
1859             return getFirewallType(chain) == FIREWALL_WHITELIST
1860                     ? INetd.FIREWALL_RULE_DENY : INetd.FIREWALL_RULE_ALLOW;
1861         }
1862         return rule;
1863     }
1864 
enforceSystemUid()1865     private static void enforceSystemUid() {
1866         final int uid = Binder.getCallingUid();
1867         if (uid != Process.SYSTEM_UID) {
1868             throw new SecurityException("Only available to AID_SYSTEM");
1869         }
1870     }
1871 
1872     @Override
registerNetworkActivityListener(INetworkActivityListener listener)1873     public void registerNetworkActivityListener(INetworkActivityListener listener) {
1874         mNetworkActivityListeners.register(listener);
1875     }
1876 
1877     @Override
unregisterNetworkActivityListener(INetworkActivityListener listener)1878     public void unregisterNetworkActivityListener(INetworkActivityListener listener) {
1879         mNetworkActivityListeners.unregister(listener);
1880     }
1881 
1882     @Override
isNetworkActive()1883     public boolean isNetworkActive() {
1884         synchronized (mNetworkActivityListeners) {
1885             return mNetworkActive || mActiveIdleTimers.isEmpty();
1886         }
1887     }
1888 
reportNetworkActive()1889     private void reportNetworkActive() {
1890         final int length = mNetworkActivityListeners.beginBroadcast();
1891         try {
1892             for (int i = 0; i < length; i++) {
1893                 try {
1894                     mNetworkActivityListeners.getBroadcastItem(i).onNetworkActive();
1895                 } catch (RemoteException | RuntimeException e) {
1896                 }
1897             }
1898         } finally {
1899             mNetworkActivityListeners.finishBroadcast();
1900         }
1901     }
1902 
1903     @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)1904     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1905         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
1906 
1907         pw.print("mMobileActivityFromRadio="); pw.print(mMobileActivityFromRadio);
1908                 pw.print(" mLastPowerStateFromRadio="); pw.println(mLastPowerStateFromRadio);
1909         pw.print("mNetworkActive="); pw.println(mNetworkActive);
1910 
1911         synchronized (mQuotaLock) {
1912             pw.print("Active quota ifaces: "); pw.println(mActiveQuotas.toString());
1913             pw.print("Active alert ifaces: "); pw.println(mActiveAlerts.toString());
1914             pw.print("Data saver mode: "); pw.println(mDataSaverMode);
1915             synchronized (mRulesLock) {
1916                 dumpUidRuleOnQuotaLocked(pw, "blacklist", mUidRejectOnMetered);
1917                 dumpUidRuleOnQuotaLocked(pw, "whitelist", mUidAllowOnMetered);
1918             }
1919         }
1920 
1921         synchronized (mRulesLock) {
1922             dumpUidFirewallRule(pw, "", mUidFirewallRules);
1923 
1924             pw.print("UID firewall standby chain enabled: "); pw.println(
1925                     getFirewallChainState(FIREWALL_CHAIN_STANDBY));
1926             dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_STANDBY, mUidFirewallStandbyRules);
1927 
1928             pw.print("UID firewall dozable chain enabled: "); pw.println(
1929                     getFirewallChainState(FIREWALL_CHAIN_DOZABLE));
1930             dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_DOZABLE, mUidFirewallDozableRules);
1931 
1932             pw.println("UID firewall powersave chain enabled: " +
1933                     getFirewallChainState(FIREWALL_CHAIN_POWERSAVE));
1934             dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_POWERSAVE, mUidFirewallPowerSaveRules);
1935         }
1936 
1937         synchronized (mIdleTimerLock) {
1938             pw.println("Idle timers:");
1939             for (HashMap.Entry<String, IdleTimerParams> ent : mActiveIdleTimers.entrySet()) {
1940                 pw.print("  "); pw.print(ent.getKey()); pw.println(":");
1941                 IdleTimerParams params = ent.getValue();
1942                 pw.print("    timeout="); pw.print(params.timeout);
1943                 pw.print(" type="); pw.print(params.type);
1944                 pw.print(" networkCount="); pw.println(params.networkCount);
1945             }
1946         }
1947 
1948         pw.print("Firewall enabled: "); pw.println(mFirewallEnabled);
1949         pw.print("Netd service status: " );
1950         if (mNetdService == null) {
1951             pw.println("disconnected");
1952         } else {
1953             try {
1954                 final boolean alive = mNetdService.isAlive();
1955                 pw.println(alive ? "alive": "dead");
1956             } catch (RemoteException e) {
1957                 pw.println("unreachable");
1958             }
1959         }
1960     }
1961 
dumpUidRuleOnQuotaLocked(PrintWriter pw, String name, SparseBooleanArray list)1962     private void dumpUidRuleOnQuotaLocked(PrintWriter pw, String name, SparseBooleanArray list) {
1963         pw.print("UID bandwith control ");
1964         pw.print(name);
1965         pw.print(" rule: [");
1966         final int size = list.size();
1967         for (int i = 0; i < size; i++) {
1968             pw.print(list.keyAt(i));
1969             if (i < size - 1) pw.print(",");
1970         }
1971         pw.println("]");
1972     }
1973 
dumpUidFirewallRule(PrintWriter pw, String name, SparseIntArray rules)1974     private void dumpUidFirewallRule(PrintWriter pw, String name, SparseIntArray rules) {
1975         pw.print("UID firewall ");
1976         pw.print(name);
1977         pw.print(" rule: [");
1978         final int size = rules.size();
1979         for (int i = 0; i < size; i++) {
1980             pw.print(rules.keyAt(i));
1981             pw.print(":");
1982             pw.print(rules.valueAt(i));
1983             if (i < size - 1) pw.print(",");
1984         }
1985         pw.println("]");
1986     }
1987 
1988     @Override
addInterfaceToNetwork(String iface, int netId)1989     public void addInterfaceToNetwork(String iface, int netId) {
1990         modifyInterfaceInNetwork(MODIFY_OPERATION_ADD, netId, iface);
1991     }
1992 
1993     @Override
removeInterfaceFromNetwork(String iface, int netId)1994     public void removeInterfaceFromNetwork(String iface, int netId) {
1995         modifyInterfaceInNetwork(MODIFY_OPERATION_REMOVE, netId, iface);
1996     }
1997 
modifyInterfaceInNetwork(boolean add, int netId, String iface)1998     private void modifyInterfaceInNetwork(boolean add, int netId, String iface) {
1999         NetworkStack.checkNetworkStackPermission(mContext);
2000         try {
2001             if (add) {
2002                 mNetdService.networkAddInterface(netId, iface);
2003             } else {
2004                 mNetdService.networkRemoveInterface(netId, iface);
2005             }
2006         } catch (RemoteException | ServiceSpecificException e) {
2007             throw new IllegalStateException(e);
2008         }
2009     }
2010 
2011     @Override
addLegacyRouteForNetId(int netId, RouteInfo routeInfo, int uid)2012     public void addLegacyRouteForNetId(int netId, RouteInfo routeInfo, int uid) {
2013         NetworkStack.checkNetworkStackPermission(mContext);
2014 
2015         final LinkAddress la = routeInfo.getDestinationLinkAddress();
2016         final String ifName = routeInfo.getInterface();
2017         final String dst = la.toString();
2018         final String nextHop;
2019 
2020         if (routeInfo.hasGateway()) {
2021             nextHop = routeInfo.getGateway().getHostAddress();
2022         } else {
2023             nextHop = "";
2024         }
2025         try {
2026             mNetdService.networkAddLegacyRoute(netId, ifName, dst, nextHop, uid);
2027         } catch (RemoteException | ServiceSpecificException e) {
2028             throw new IllegalStateException(e);
2029         }
2030     }
2031 
2032     @Override
setDefaultNetId(int netId)2033     public void setDefaultNetId(int netId) {
2034         NetworkStack.checkNetworkStackPermission(mContext);
2035 
2036         try {
2037             mNetdService.networkSetDefault(netId);
2038         } catch (RemoteException | ServiceSpecificException e) {
2039             throw new IllegalStateException(e);
2040         }
2041     }
2042 
2043     @Override
clearDefaultNetId()2044     public void clearDefaultNetId() {
2045         NetworkStack.checkNetworkStackPermission(mContext);
2046 
2047         try {
2048             mNetdService.networkClearDefault();
2049         } catch (RemoteException | ServiceSpecificException e) {
2050             throw new IllegalStateException(e);
2051         }
2052     }
2053 
2054     @Override
setNetworkPermission(int netId, int permission)2055     public void setNetworkPermission(int netId, int permission) {
2056         NetworkStack.checkNetworkStackPermission(mContext);
2057 
2058         try {
2059             mNetdService.networkSetPermissionForNetwork(netId, permission);
2060         } catch (RemoteException | ServiceSpecificException e) {
2061             throw new IllegalStateException(e);
2062         }
2063     }
2064 
2065     @Override
allowProtect(int uid)2066     public void allowProtect(int uid) {
2067         NetworkStack.checkNetworkStackPermission(mContext);
2068 
2069         try {
2070             mNetdService.networkSetProtectAllow(uid);
2071         } catch (RemoteException | ServiceSpecificException e) {
2072             throw new IllegalStateException(e);
2073         }
2074     }
2075 
2076     @Override
denyProtect(int uid)2077     public void denyProtect(int uid) {
2078         NetworkStack.checkNetworkStackPermission(mContext);
2079 
2080         try {
2081             mNetdService.networkSetProtectDeny(uid);
2082         } catch (RemoteException | ServiceSpecificException e) {
2083             throw new IllegalStateException(e);
2084         }
2085     }
2086 
2087     @Override
addInterfaceToLocalNetwork(String iface, List<RouteInfo> routes)2088     public void addInterfaceToLocalNetwork(String iface, List<RouteInfo> routes) {
2089         modifyInterfaceInNetwork(MODIFY_OPERATION_ADD, INetd.LOCAL_NET_ID, iface);
2090         // modifyInterfaceInNetwork already check calling permission.
2091         RouteUtils.addRoutesToLocalNetwork(mNetdService, iface, routes);
2092     }
2093 
2094     @Override
removeInterfaceFromLocalNetwork(String iface)2095     public void removeInterfaceFromLocalNetwork(String iface) {
2096         modifyInterfaceInNetwork(MODIFY_OPERATION_REMOVE, INetd.LOCAL_NET_ID, iface);
2097     }
2098 
2099     @Override
removeRoutesFromLocalNetwork(List<RouteInfo> routes)2100     public int removeRoutesFromLocalNetwork(List<RouteInfo> routes) {
2101         NetworkStack.checkNetworkStackPermission(mContext);
2102         return RouteUtils.removeRoutesFromLocalNetwork(mNetdService, routes);
2103     }
2104 
2105     @Override
isNetworkRestricted(int uid)2106     public boolean isNetworkRestricted(int uid) {
2107         mContext.enforceCallingOrSelfPermission(OBSERVE_NETWORK_POLICY, TAG);
2108         return isNetworkRestrictedInternal(uid);
2109     }
2110 
isNetworkRestrictedInternal(int uid)2111     private boolean isNetworkRestrictedInternal(int uid) {
2112         synchronized (mRulesLock) {
2113             if (getFirewallChainState(FIREWALL_CHAIN_STANDBY)
2114                     && mUidFirewallStandbyRules.get(uid) == FIREWALL_RULE_DENY) {
2115                 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of app standby mode");
2116                 return true;
2117             }
2118             if (getFirewallChainState(FIREWALL_CHAIN_DOZABLE)
2119                     && mUidFirewallDozableRules.get(uid) != FIREWALL_RULE_ALLOW) {
2120                 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of device idle mode");
2121                 return true;
2122             }
2123             if (getFirewallChainState(FIREWALL_CHAIN_POWERSAVE)
2124                     && mUidFirewallPowerSaveRules.get(uid) != FIREWALL_RULE_ALLOW) {
2125                 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of power saver mode");
2126                 return true;
2127             }
2128             if (mUidRejectOnMetered.get(uid)) {
2129                 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of no metered data"
2130                         + " in the background");
2131                 return true;
2132             }
2133             if (mDataSaverMode && !mUidAllowOnMetered.get(uid)) {
2134                 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of data saver mode");
2135                 return true;
2136             }
2137             return false;
2138         }
2139     }
2140 
setFirewallChainState(int chain, boolean state)2141     private void setFirewallChainState(int chain, boolean state) {
2142         synchronized (mRulesLock) {
2143             mFirewallChainStates.put(chain, state);
2144         }
2145     }
2146 
getFirewallChainState(int chain)2147     private boolean getFirewallChainState(int chain) {
2148         synchronized (mRulesLock) {
2149             return mFirewallChainStates.get(chain);
2150         }
2151     }
2152 
2153     @VisibleForTesting
2154     class LocalService extends NetworkManagementInternal {
2155         @Override
isNetworkRestrictedForUid(int uid)2156         public boolean isNetworkRestrictedForUid(int uid) {
2157             return isNetworkRestrictedInternal(uid);
2158         }
2159     }
2160 
2161     @VisibleForTesting
getInjector()2162     Injector getInjector() {
2163         return new Injector();
2164     }
2165 
2166     @VisibleForTesting
2167     class Injector {
setDataSaverMode(boolean dataSaverMode)2168         void setDataSaverMode(boolean dataSaverMode) {
2169             mDataSaverMode = dataSaverMode;
2170         }
2171 
setFirewallChainState(int chain, boolean state)2172         void setFirewallChainState(int chain, boolean state) {
2173             NetworkManagementService.this.setFirewallChainState(chain, state);
2174         }
2175 
setFirewallRule(int chain, int uid, int rule)2176         void setFirewallRule(int chain, int uid, int rule) {
2177             synchronized (mRulesLock) {
2178                 getUidFirewallRulesLR(chain).put(uid, rule);
2179             }
2180         }
2181 
setUidOnMeteredNetworkList(boolean blacklist, int uid, boolean enable)2182         void setUidOnMeteredNetworkList(boolean blacklist, int uid, boolean enable) {
2183             synchronized (mRulesLock) {
2184                 if (blacklist) {
2185                     mUidRejectOnMetered.put(uid, enable);
2186                 } else {
2187                     mUidAllowOnMetered.put(uid, enable);
2188                 }
2189             }
2190         }
2191 
reset()2192         void reset() {
2193             synchronized (mRulesLock) {
2194                 setDataSaverMode(false);
2195                 final int[] chains = {
2196                         FIREWALL_CHAIN_DOZABLE,
2197                         FIREWALL_CHAIN_STANDBY,
2198                         FIREWALL_CHAIN_POWERSAVE
2199                 };
2200                 for (int chain : chains) {
2201                     setFirewallChainState(chain, false);
2202                     getUidFirewallRulesLR(chain).clear();
2203                 }
2204                 mUidAllowOnMetered.clear();
2205                 mUidRejectOnMetered.clear();
2206             }
2207         }
2208     }
2209 }
2210