Move ApfFilter from ConnectivityService to IpManager

There's a few advantages to having ApfFilter in IpManager:
1. If things go wrong, crashing a particular transport is less bad then
   crashing ConnectivityService.  We also don't want to use
   ConnectivityService as a dumping ground for transport-specific logic.
2. This makes implementing WifiManager.MulticastLock a lot simpler and
   safer because enabling/disabling it doesn't have to go through the
   NetworkAgent, which could risk various races (e.g. installing a filter
   into the wrong WiFi network).
3. IpManager is the ultimate source for LinkProperties for a particular
   transport and since ApfFilter uses the LinkProperties it's better to
   have it closely paired with the IpManager. Likewise, ApfFilter needs
   to know the APF capabilities of the transport, so having it in
   the transport avoids having to parcel this information through the
   NetworkAgent.

Bug: 26238573
Change-Id: I99b85f2b64972f0e7572170ec5d1926081aa3429
This commit is contained in:
Paul Jensen
2016-03-18 12:22:09 -04:00
parent 1ed762c929
commit 6b7f7a0852
5 changed files with 46 additions and 99 deletions

View File

@@ -200,14 +200,6 @@ public abstract class NetworkAgent extends Handler {
*/
public static final int CMD_PREVENT_AUTOMATIC_RECONNECT = BASE + 15;
/**
* Sent by ConnectivityService to the NetworkAgent to install an APF program in the network
* chipset for use to filter packets.
*
* obj = byte[] containing the APF program bytecode.
*/
public static final int CMD_PUSH_APF_PROGRAM = BASE + 16;
public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
NetworkCapabilities nc, LinkProperties lp, int score) {
this(looper, context, logTag, ni, nc, lp, score, null);
@@ -327,10 +319,6 @@ public abstract class NetworkAgent extends Handler {
preventAutomaticReconnect();
break;
}
case CMD_PUSH_APF_PROGRAM: {
installPacketFilter((byte[]) msg.obj);
break;
}
}
}
@@ -506,15 +494,6 @@ public abstract class NetworkAgent extends Handler {
protected void preventAutomaticReconnect() {
}
/**
* Install a packet filter.
* @param filter an APF program to filter incoming packets.
* @return {@code true} if filter successfully installed, {@code false} otherwise.
*/
protected boolean installPacketFilter(byte[] filter) {
return false;
}
protected void log(String s) {
Log.d(LOG_TAG, "NetworkAgent: " + s);
}

View File

@@ -56,22 +56,6 @@ public class NetworkMisc implements Parcelable {
*/
public String subscriberId;
/**
* Version of APF instruction set supported for packet filtering. 0 indicates no support for
* packet filtering using APF programs.
*/
public int apfVersionSupported;
/**
* Maximum size of APF program allowed.
*/
public int maximumApfProgramSize;
/**
* Format of packets passed to APF filter. Should be one of ARPHRD_*
*/
public int apfPacketFormat;
public NetworkMisc() {
}
@@ -81,9 +65,6 @@ public class NetworkMisc implements Parcelable {
explicitlySelected = nm.explicitlySelected;
acceptUnvalidated = nm.acceptUnvalidated;
subscriberId = nm.subscriberId;
apfVersionSupported = nm.apfVersionSupported;
maximumApfProgramSize = nm.maximumApfProgramSize;
apfPacketFormat = nm.apfPacketFormat;
}
}
@@ -98,9 +79,6 @@ public class NetworkMisc implements Parcelable {
out.writeInt(explicitlySelected ? 1 : 0);
out.writeInt(acceptUnvalidated ? 1 : 0);
out.writeString(subscriberId);
out.writeInt(apfVersionSupported);
out.writeInt(maximumApfProgramSize);
out.writeInt(apfPacketFormat);
}
public static final Creator<NetworkMisc> CREATOR = new Creator<NetworkMisc>() {
@@ -111,9 +89,6 @@ public class NetworkMisc implements Parcelable {
networkMisc.explicitlySelected = in.readInt() != 0;
networkMisc.acceptUnvalidated = in.readInt() != 0;
networkMisc.subscriberId = in.readString();
networkMisc.apfVersionSupported = in.readInt();
networkMisc.maximumApfProgramSize = in.readInt();
networkMisc.apfPacketFormat = in.readInt();
return networkMisc;
}

View File

@@ -126,7 +126,6 @@ import com.android.server.connectivity.NetworkAgentInfo;
import com.android.server.connectivity.NetworkMonitor;
import com.android.server.connectivity.PacManager;
import com.android.server.connectivity.PermissionMonitor;
import com.android.server.connectivity.ApfFilter;
import com.android.server.connectivity.Tethering;
import com.android.server.connectivity.Vpn;
import com.android.server.net.BaseNetworkObserver;
@@ -355,13 +354,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
*/
private static final int EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT = 31;
/**
* used to push APF program to NetworkAgent
* replyTo = NetworkAgent message handler
* obj = byte[] of APF program
*/
private static final int EVENT_PUSH_APF_PROGRAM_TO_NETWORK = 32;
/** Handler thread used for both of the handlers below. */
@VisibleForTesting
protected final HandlerThread mHandlerThread;
@@ -1803,20 +1795,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
private void dumpApf(IndentingPrintWriter pw) {
pw.println("APF filters:");
pw.increaseIndent();
for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
if (nai.apfFilter != null) {
pw.println(nai.name() + ":");
pw.increaseIndent();
nai.apfFilter.dump(pw);
pw.decreaseIndent();
}
}
pw.decreaseIndent();
}
@Override
protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
@@ -1834,11 +1812,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
return;
}
if (argsContain(args, "apf")) {
dumpApf(pw);
return;
}
pw.print("NetworkFactories for:");
for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
pw.print(" " + nfi.name);
@@ -1902,7 +1875,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
mKeepaliveTracker.dump(pw);
pw.println();
dumpApf(pw);
if (mInetLog != null && mInetLog.size() > 0) {
pw.println();
@@ -2224,7 +2196,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
mKeepaliveTracker.handleStopAllKeepalives(nai,
ConnectivityManager.PacketKeepalive.ERROR_INVALID_NETWORK);
nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_DISCONNECTED);
if (nai.apfFilter != null) nai.apfFilter.shutdown();
mNetworkAgentInfos.remove(msg.replyTo);
updateClat(null, nai.linkProperties, nai);
synchronized (mNetworkForNetId) {
@@ -2439,13 +2410,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
accept ? 1 : 0, always ? 1: 0, network));
}
public void pushApfProgramToNetwork(NetworkAgentInfo nai, byte[] program) {
enforceConnectivityInternalPermission();
Message msg = mHandler.obtainMessage(EVENT_PUSH_APF_PROGRAM_TO_NETWORK, program);
msg.replyTo = nai.messenger;
mHandler.sendMessage(msg);
}
private void handleSetAcceptUnvalidated(Network network, boolean accept, boolean always) {
if (DBG) log("handleSetAcceptUnvalidated network=" + network +
" accept=" + accept + " always=" + always);
@@ -2595,16 +2559,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
handleMobileDataAlwaysOn();
break;
}
case EVENT_PUSH_APF_PROGRAM_TO_NETWORK: {
NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
if (nai == null) {
loge("EVENT_PUSH_APF_PROGRAM_TO_NETWORK from unknown NetworkAgent");
} else {
nai.asyncChannel.sendMessage(NetworkAgent.CMD_PUSH_APF_PROGRAM,
(byte[]) msg.obj);
}
break;
}
// Sent by KeepaliveTracker to process an app request on the state machine thread.
case NetworkAgent.CMD_START_PACKET_KEEPALIVE: {
mKeepaliveTracker.handleStartKeepalive(msg);
@@ -4186,9 +4140,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (networkAgent.clatd != null) {
networkAgent.clatd.fixupLinkProperties(oldLp);
}
if (networkAgent.apfFilter != null) {
networkAgent.apfFilter.updateFilter();
}
updateInterfaces(newLp, oldLp, netId);
updateMtu(newLp, oldLp);

View File

@@ -32,7 +32,6 @@ import android.util.SparseArray;
import com.android.internal.util.AsyncChannel;
import com.android.server.ConnectivityService;
import com.android.server.connectivity.NetworkMonitor;
import com.android.server.connectivity.ApfFilter;
import java.util.ArrayList;
import java.util.Comparator;
@@ -164,8 +163,6 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
// Used by ConnectivityService to keep track of 464xlat.
public Nat464Xlat clatd;
public ApfFilter apfFilter;
public NetworkAgentInfo(Messenger messenger, AsyncChannel ac, Network net, NetworkInfo info,
LinkProperties lp, NetworkCapabilities nc, int score, Context context, Handler handler,
NetworkMisc misc, NetworkRequest defaultRequest, ConnectivityService connService) {
@@ -178,7 +175,6 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
currentScore = score;
networkMonitor = connService.createNetworkMonitor(context, handler, this, defaultRequest);
networkMisc = misc;
apfFilter.maybeInstall(connService, this);
}
/**

View File

@@ -0,0 +1,46 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.net.apf;
/**
* APF program support capabilities.
*
* @hide
*/
public class ApfCapabilities {
/**
* Version of APF instruction set supported for packet filtering. 0 indicates no support for
* packet filtering using APF programs.
*/
public final int apfVersionSupported;
/**
* Maximum size of APF program allowed.
*/
public final int maximumApfProgramSize;
/**
* Format of packets passed to APF filter. Should be one of ARPHRD_*
*/
public final int apfPacketFormat;
ApfCapabilities(int apfVersionSupported, int maximumApfProgramSize, int apfPacketFormat) {
this.apfVersionSupported = apfVersionSupported;
this.maximumApfProgramSize = maximumApfProgramSize;
this.apfPacketFormat = apfPacketFormat;
}
}