summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Paul Jensen <pauljensen@google.com> 2016-03-18 12:22:09 -0400
committer Paul Jensen <pauljensen@google.com> 2016-03-25 07:46:07 -0400
commitf21b4dc1d6e9cc3fc164828e9eba33445c0801d0 (patch)
tree25b772056056c45606cf07c1f6eb724b334d5bcc
parentdfd5a949fbbba78793c261f5a0d585b27dc33851 (diff)
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
-rw-r--r--core/java/android/net/NetworkAgent.java21
-rw-r--r--core/java/android/net/NetworkMisc.java25
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java49
-rw-r--r--services/core/java/com/android/server/connectivity/NetworkAgentInfo.java4
-rw-r--r--services/net/java/android/net/apf/ApfCapabilities.java46
-rw-r--r--services/net/java/android/net/apf/ApfFilter.java (renamed from services/core/java/com/android/server/connectivity/ApfFilter.java)89
-rw-r--r--services/net/java/android/net/ip/IpManager.java47
7 files changed, 122 insertions, 159 deletions
diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java
index 9e360e11bf8b..20c216826531 100644
--- a/core/java/android/net/NetworkAgent.java
+++ b/core/java/android/net/NetworkAgent.java
@@ -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);
}
diff --git a/core/java/android/net/NetworkMisc.java b/core/java/android/net/NetworkMisc.java
index 748699eff4cf..5511a248b6aa 100644
--- a/core/java/android/net/NetworkMisc.java
+++ b/core/java/android/net/NetworkMisc.java
@@ -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;
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index d88ddfd3f426..95d3cc3bbcf0 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -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);
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index b4c71c13a7e7..c5d38cb73d04 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -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);
}
/**
diff --git a/services/net/java/android/net/apf/ApfCapabilities.java b/services/net/java/android/net/apf/ApfCapabilities.java
new file mode 100644
index 000000000000..f169411b385c
--- /dev/null
+++ b/services/net/java/android/net/apf/ApfCapabilities.java
@@ -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;
+ }
+} \ No newline at end of file
diff --git a/services/core/java/com/android/server/connectivity/ApfFilter.java b/services/net/java/android/net/apf/ApfFilter.java
index 35f358353cbf..ebbf99101e42 100644
--- a/services/core/java/com/android/server/connectivity/ApfFilter.java
+++ b/services/net/java/android/net/apf/ApfFilter.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server.connectivity;
+package android.net.apf;
import static android.system.OsConstants.*;
@@ -22,6 +22,7 @@ import android.net.NetworkUtils;
import android.net.apf.ApfGenerator;
import android.net.apf.ApfGenerator.IllegalInstructionException;
import android.net.apf.ApfGenerator.Register;
+import android.net.ip.IpManager;
import android.system.ErrnoException;
import android.system.Os;
import android.system.PacketSocketAddress;
@@ -31,7 +32,6 @@ import android.util.Pair;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.HexDump;
import com.android.internal.util.IndentingPrintWriter;
-import com.android.server.ConnectivityService;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -136,24 +136,27 @@ public class ApfFilter {
// NOTE: this must be added to the IPv4 header length in IPV4_HEADER_SIZE_MEMORY_SLOT
private static final int DHCP_CLIENT_MAC_OFFSET = ETH_HEADER_LEN + UDP_HEADER_LEN + 28;
- private final ConnectivityService mConnectivityService;
- private final NetworkAgentInfo mNai;
+ private final ApfCapabilities mApfCapabilities;
+ private final IpManager.Callback mIpManagerCallback;
+ private final NetworkInterface mNetworkInterface;
+ private byte[] mHardwareAddress;
private ReceiveThread mReceiveThread;
- private String mIfaceName;
- private byte[] mIfaceMac;
@GuardedBy("this")
private long mUniqueCounter;
@GuardedBy("this")
private boolean mMulticastFilter;
- private ApfFilter(ConnectivityService connectivityService, NetworkAgentInfo nai) {
- mConnectivityService = connectivityService;
- mNai = nai;
+ private ApfFilter(ApfCapabilities apfCapabilities, NetworkInterface networkInterface,
+ IpManager.Callback ipManagerCallback) {
+ mApfCapabilities = apfCapabilities;
+ mIpManagerCallback = ipManagerCallback;
+ mNetworkInterface = networkInterface;
+
maybeStartFilter();
}
private void log(String s) {
- Log.d(TAG, "(" + mNai.network.netId + "): " + s);
+ Log.d(TAG, "(" + mNetworkInterface.getName() + "): " + s);
}
@GuardedBy("this")
@@ -166,27 +169,18 @@ public class ApfFilter {
* filters to ignore useless RAs.
*/
private void maybeStartFilter() {
- mIfaceName = mNai.linkProperties.getInterfaceName();
- if (mIfaceName == null) return;
FileDescriptor socket;
try {
- NetworkInterface networkInterface = NetworkInterface.getByName(mIfaceName);
- if (networkInterface == null) {
- Log.e(TAG, "Can't find interface " + mIfaceName);
- return;
- }
- mIfaceMac = networkInterface.getHardwareAddress();
-
+ mHardwareAddress = mNetworkInterface.getHardwareAddress();
synchronized(this) {
// Install basic filters
installNewProgramLocked();
}
-
socket = Os.socket(AF_PACKET, SOCK_RAW, ETH_P_IPV6);
PacketSocketAddress addr = new PacketSocketAddress((short) ETH_P_IPV6,
- networkInterface.getIndex());
+ mNetworkInterface.getIndex());
Os.bind(socket, addr);
- NetworkUtils.attachRaFilter(socket, mNai.networkMisc.apfPacketFormat);
+ NetworkUtils.attachRaFilter(socket, mApfCapabilities.apfPacketFormat);
} catch(SocketException|ErrnoException e) {
Log.e(TAG, "Error starting filter", e);
return;
@@ -195,20 +189,6 @@ public class ApfFilter {
mReceiveThread.start();
}
- /**
- * mNai's LinkProperties may have changed, take appropriate action.
- */
- public void updateFilter() {
- // If we're not listening for RAs, try starting.
- if (mReceiveThread == null) {
- maybeStartFilter();
- // If interface name has changed, restart.
- } else if (!mIfaceName.equals(mNai.linkProperties.getInterfaceName())) {
- shutdown();
- maybeStartFilter();
- }
- }
-
// Returns seconds since Unix Epoch.
private static long curTime() {
return System.currentTimeMillis() / 1000L;
@@ -574,7 +554,7 @@ public class ApfFilter {
gen.addLoadImmediate(Register.R0, DHCP_CLIENT_MAC_OFFSET);
// NOTE: Relies on R1 containing IPv4 header offset.
gen.addAddR1();
- gen.addJumpIfBytesNotEqual(Register.R0, mIfaceMac, gen.DROP_LABEL);
+ gen.addJumpIfBytesNotEqual(Register.R0, mHardwareAddress, gen.DROP_LABEL);
// Otherwise, pass
gen.addJump(gen.PASS_LABEL);
@@ -632,7 +612,7 @@ public class ApfFilter {
private ApfGenerator beginProgramLocked() throws IllegalInstructionException {
ApfGenerator gen = new ApfGenerator();
// This is guaranteed to return true because of the check in maybeCreate.
- gen.setApfVersion(mNai.networkMisc.apfVersionSupported);
+ gen.setApfVersion(mApfCapabilities.apfVersionSupported);
// Here's a basic summary of what the initial program does:
//
@@ -673,7 +653,7 @@ public class ApfFilter {
for (Ra ra : mRas) {
ra.generateFilterLocked(gen);
// Stop if we get too big.
- if (gen.programLengthOverEstimate() > mNai.networkMisc.maximumApfProgramSize) break;
+ if (gen.programLengthOverEstimate() > mApfCapabilities.maximumApfProgramSize) break;
rasToFilter.add(ra);
}
// Step 2: Actually generate the program
@@ -694,7 +674,7 @@ public class ApfFilter {
if (VDBG) {
hexDump("Installing filter: ", program, program.length);
}
- mConnectivityService.pushApfProgramToNetwork(mNai, program);
+ mIpManagerCallback.installPacketFilter(program);
}
// Install a new filter program if the last installed one will die soon.
@@ -768,26 +748,27 @@ public class ApfFilter {
}
/**
- * Install an {@link ApfFilter} on {@code nai} if {@code nai} supports packet
+ * Create an {@link ApfFilter} if {@code apfCapabilities} indicates support for packet
* filtering using APF programs.
*/
- public static void maybeInstall(ConnectivityService connectivityService, NetworkAgentInfo nai) {
- if (nai.networkMisc == null) return;
- if (nai.networkMisc.apfVersionSupported == 0) return;
- if (nai.networkMisc.maximumApfProgramSize < 512) {
- Log.e(TAG, "Unacceptably small APF limit: " + nai.networkMisc.maximumApfProgramSize);
- return;
+ public static ApfFilter maybeCreate(ApfCapabilities apfCapabilities,
+ NetworkInterface networkInterface, IpManager.Callback ipManagerCallback) {
+ if (apfCapabilities == null || networkInterface == null) return null;
+ if (apfCapabilities.apfVersionSupported == 0) return null;
+ if (apfCapabilities.maximumApfProgramSize < 512) {
+ Log.e(TAG, "Unacceptably small APF limit: " + apfCapabilities.maximumApfProgramSize);
+ return null;
}
// For now only support generating programs for Ethernet frames. If this restriction is
// lifted:
// 1. the program generator will need its offsets adjusted.
// 2. the packet filter attached to our packet socket will need its offset adjusted.
- if (nai.networkMisc.apfPacketFormat != ARPHRD_ETHER) return;
- if (!new ApfGenerator().setApfVersion(nai.networkMisc.apfVersionSupported)) {
- Log.e(TAG, "Unsupported APF version: " + nai.networkMisc.apfVersionSupported);
- return;
+ if (apfCapabilities.apfPacketFormat != ARPHRD_ETHER) return null;
+ if (!new ApfGenerator().setApfVersion(apfCapabilities.apfVersionSupported)) {
+ Log.e(TAG, "Unsupported APF version: " + apfCapabilities.apfVersionSupported);
+ return null;
}
- nai.apfFilter = new ApfFilter(connectivityService, nai);
+ return new ApfFilter(apfCapabilities, networkInterface, ipManagerCallback);
}
public synchronized void shutdown() {
@@ -807,8 +788,8 @@ public class ApfFilter {
}
public synchronized void dump(IndentingPrintWriter pw) {
- pw.println("APF version: " + mNai.networkMisc.apfVersionSupported);
- pw.println("Max program size: " + mNai.networkMisc.maximumApfProgramSize);
+ pw.println("APF version: " + mApfCapabilities.apfVersionSupported);
+ pw.println("Max program size: " + mApfCapabilities.maximumApfProgramSize);
pw.println("Receive thread: " + (mReceiveThread != null ? "RUNNING" : "STOPPED"));
if (mLastTimeInstalledProgram == 0) {
pw.println("No program installed.");
diff --git a/services/net/java/android/net/ip/IpManager.java b/services/net/java/android/net/ip/IpManager.java
index c7c50153f855..66c7909e5b2a 100644
--- a/services/net/java/android/net/ip/IpManager.java
+++ b/services/net/java/android/net/ip/IpManager.java
@@ -19,6 +19,8 @@ package android.net.ip;
import com.android.internal.util.MessageUtils;
import android.content.Context;
+import android.net.apf.ApfCapabilities;
+import android.net.apf.ApfFilter;
import android.net.DhcpResults;
import android.net.InterfaceConfiguration;
import android.net.LinkAddress;
@@ -38,10 +40,12 @@ import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
import com.android.server.net.NetlinkTracker;
+import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
@@ -108,6 +112,9 @@ public class IpManager extends StateMachine {
// Called when the IpManager state machine terminates.
public void onQuit() {}
+
+ // Install an APF program to filter incoming packets.
+ public void installPacketFilter(byte[] filter) {}
}
public static class WaitForProvisioningCallback extends Callback {
@@ -179,6 +186,11 @@ public class IpManager extends StateMachine {
return this;
}
+ public Builder withApfCapabilities(ApfCapabilities apfCapabilities) {
+ mConfig.mApfCapabilities = apfCapabilities;
+ return this;
+ }
+
public ProvisioningConfiguration build() {
return new ProvisioningConfiguration(mConfig);
}
@@ -187,6 +199,7 @@ public class IpManager extends StateMachine {
/* package */ boolean mUsingIpReachabilityMonitor = true;
/* package */ boolean mRequestedPreDhcpAction;
/* package */ StaticIpConfiguration mStaticIpConfig;
+ /* package */ ApfCapabilities mApfCapabilities;
public ProvisioningConfiguration() {}
@@ -194,6 +207,7 @@ public class IpManager extends StateMachine {
mUsingIpReachabilityMonitor = other.mUsingIpReachabilityMonitor;
mRequestedPreDhcpAction = other.mRequestedPreDhcpAction;
mStaticIpConfig = other.mStaticIpConfig;
+ mApfCapabilities = other.mApfCapabilities;
}
}
@@ -229,7 +243,7 @@ public class IpManager extends StateMachine {
private final INetworkManagementService mNwService;
private final NetlinkTracker mNetlinkTracker;
- private int mInterfaceIndex;
+ private NetworkInterface mNetworkInterface;
/**
* Non-final member variables accessed only from within our StateMachine.
@@ -240,6 +254,7 @@ public class IpManager extends StateMachine {
private DhcpResults mDhcpResults;
private String mTcpBufferSizes;
private ProxyInfo mHttpProxy;
+ private ApfFilter mApfFilter;
/**
* Member variables accessed both from within the StateMachine thread
@@ -325,7 +340,7 @@ public class IpManager extends StateMachine {
}
public void startProvisioning(ProvisioningConfiguration req) {
- getInterfaceIndex();
+ getNetworkInterface();
sendMessage(CMD_START, new ProvisioningConfiguration(req));
}
@@ -378,6 +393,19 @@ public class IpManager extends StateMachine {
}
}
+ public void dumpApf(PrintWriter writer) {
+ writer.println("--------------------------------------------------------------------");
+ writer.println("APF dump:");
+ // Thread-unsafe access to mApfFilter but just used for debugging.
+ ApfFilter apfFilter = mApfFilter;
+ if (apfFilter != null) {
+ apfFilter.dump(new IndentingPrintWriter(writer, " "));
+ } else {
+ writer.println("No apf support");
+ }
+ writer.println("--------------------------------------------------------------------");
+ }
+
/**
* Internals.
@@ -392,7 +420,7 @@ public class IpManager extends StateMachine {
protected String getLogRecString(Message msg) {
final String logLine = String.format(
"iface{%s/%d} arg1{%d} arg2{%d} obj{%s}",
- mInterfaceName, mInterfaceIndex,
+ mInterfaceName, mNetworkInterface == null ? -1 : mNetworkInterface.getIndex(),
msg.arg1, msg.arg2, Objects.toString(msg.obj));
if (VDBG) {
Log.d(mTag, getWhatToString(msg.what) + " " + logLine);
@@ -400,12 +428,12 @@ public class IpManager extends StateMachine {
return logLine;
}
- private void getInterfaceIndex() {
+ private void getNetworkInterface() {
try {
- mInterfaceIndex = NetworkInterface.getByName(mInterfaceName).getIndex();
+ mNetworkInterface = NetworkInterface.getByName(mInterfaceName);
} catch (SocketException | NullPointerException e) {
// TODO: throw new IllegalStateException.
- Log.e(mTag, "ALERT: Failed to get interface index: ", e);
+ Log.e(mTag, "ALERT: Failed to get interface object: ", e);
}
}
@@ -732,6 +760,8 @@ public class IpManager extends StateMachine {
class StartedState extends State {
@Override
public void enter() {
+ mApfFilter = ApfFilter.maybeCreate(mConfiguration.mApfCapabilities, mNetworkInterface,
+ mCallback);
// Set privacy extensions.
try {
mNwService.setInterfaceIpv6PrivacyExtensions(mInterfaceName, true);
@@ -788,6 +818,11 @@ public class IpManager extends StateMachine {
mDhcpClient.doQuit();
}
+ if (mApfFilter != null) {
+ mApfFilter.shutdown();
+ mApfFilter = null;
+ }
+
resetLinkProperties();
}