Skip to content
Snippets Groups Projects
Commit b15fcce2 authored by Lorenzo Colitti's avatar Lorenzo Colitti
Browse files

Add support for TAP interfaces in TestNetworkManager.

Test: builds, boots
Change-Id: I88bfd7f37c0ba0228f8288fe92212618ce134e4f
parent c72f456b
No related branches found
No related tags found
No related merge requests found
......@@ -719,6 +719,7 @@ package android.net {
}
public class TestNetworkManager {
method public android.net.TestNetworkInterface createTapInterface();
method public android.net.TestNetworkInterface createTunInterface(@NonNull android.net.LinkAddress[]);
method public void setupTestNetwork(@NonNull String, @NonNull android.os.IBinder);
method public void teardownTestNetwork(@NonNull android.net.Network);
......
......@@ -29,6 +29,7 @@ import android.os.ParcelFileDescriptor;
interface ITestNetworkManager
{
TestNetworkInterface createTunInterface(in LinkAddress[] linkAddrs);
TestNetworkInterface createTapInterface();
void setupTestNetwork(in String iface, in IBinder binder);
......
......@@ -88,4 +88,21 @@ public class TestNetworkManager {
throw e.rethrowFromSystemServer();
}
}
/**
* Create a tap interface for testing purposes
*
* @return A ParcelFileDescriptor of the underlying TAP interface. Close this to tear down the
* TAP interface.
* @hide
*/
@TestApi
public TestNetworkInterface createTapInterface() {
try {
return mService.createTapInterface();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
......@@ -60,6 +60,7 @@ class TestNetworkService extends ITestNetworkManager.Stub {
@NonNull private static final String TAG = TestNetworkService.class.getSimpleName();
@NonNull private static final String TEST_NETWORK_TYPE = "TEST_NETWORK";
@NonNull private static final String TEST_TUN_PREFIX = "testtun";
@NonNull private static final String TEST_TAP_PREFIX = "testtap";
@NonNull private static final AtomicInteger sTestTunIndex = new AtomicInteger();
@NonNull private final Context mContext;
......@@ -70,7 +71,7 @@ class TestNetworkService extends ITestNetworkManager.Stub {
@NonNull private final Handler mHandler;
// Native method stubs
private static native int jniCreateTun(@NonNull String iface);
private static native int jniCreateTunTap(boolean isTun, @NonNull String iface);
@VisibleForTesting
protected TestNetworkService(
......@@ -85,23 +86,23 @@ class TestNetworkService extends ITestNetworkManager.Stub {
}
/**
* Create a TUN interface with the given interface name and link addresses
* Create a TUN or TAP interface with the given interface name and link addresses
*
* <p>This method will return the FileDescriptor to the TUN interface. Close it to tear down the
* TUN interface.
* <p>This method will return the FileDescriptor to the interface. Close it to tear down the
* interface.
*/
@Override
public TestNetworkInterface createTunInterface(@NonNull LinkAddress[] linkAddrs) {
private TestNetworkInterface createInterface(boolean isTun, LinkAddress[] linkAddrs) {
enforceTestNetworkPermissions(mContext);
checkNotNull(linkAddrs, "missing linkAddrs");
String iface = TEST_TUN_PREFIX + sTestTunIndex.getAndIncrement();
String ifacePrefix = isTun ? TEST_TUN_PREFIX : TEST_TAP_PREFIX;
String iface = ifacePrefix + sTestTunIndex.getAndIncrement();
return Binder.withCleanCallingIdentity(
() -> {
try {
ParcelFileDescriptor tunIntf =
ParcelFileDescriptor.adoptFd(jniCreateTun(iface));
ParcelFileDescriptor.adoptFd(jniCreateTunTap(isTun, iface));
for (LinkAddress addr : linkAddrs) {
mNetd.interfaceAddAddress(
iface,
......@@ -116,6 +117,28 @@ class TestNetworkService extends ITestNetworkManager.Stub {
});
}
/**
* Create a TUN interface with the given interface name and link addresses
*
* <p>This method will return the FileDescriptor to the TUN interface. Close it to tear down the
* TUN interface.
*/
@Override
public TestNetworkInterface createTunInterface(@NonNull LinkAddress[] linkAddrs) {
return createInterface(true, linkAddrs);
}
/**
* Create a TAP interface with the given interface name
*
* <p>This method will return the FileDescriptor to the TAP interface. Close it to tear down the
* TAP interface.
*/
@Override
public TestNetworkInterface createTapInterface() {
return createInterface(false, new LinkAddress[0]);
}
// Tracker for TestNetworkAgents
@GuardedBy("mTestNetworkTracker")
@NonNull
......
......@@ -54,12 +54,12 @@ static void throwException(JNIEnv* env, int error, const char* action, const cha
jniThrowException(env, "java/lang/IllegalStateException", msg.c_str());
}
static int createTunInterface(JNIEnv* env, const char* iface) {
static int createTunTapInterface(JNIEnv* env, bool isTun, const char* iface) {
base::unique_fd tun(open("/dev/tun", O_RDWR | O_NONBLOCK));
ifreq ifr{};
// Allocate interface.
ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
ifr.ifr_flags = (isTun ? IFF_TUN : IFF_TAP) | IFF_NO_PI;
strlcpy(ifr.ifr_name, iface, IFNAMSIZ);
if (ioctl(tun.get(), TUNSETIFF, &ifr)) {
throwException(env, errno, "allocating", ifr.ifr_name);
......@@ -80,23 +80,23 @@ static int createTunInterface(JNIEnv* env, const char* iface) {
//------------------------------------------------------------------------------
static jint create(JNIEnv* env, jobject /* thiz */, jstring jIface) {
static jint create(JNIEnv* env, jobject /* thiz */, jboolean isTun, jstring jIface) {
ScopedUtfChars iface(env, jIface);
if (!iface.c_str()) {
jniThrowNullPointerException(env, "iface");
return -1;
}
int tun = createTunInterface(env, iface.c_str());
int tun = createTunTapInterface(env, isTun, iface.c_str());
// Any exceptions will be thrown from the createTunInterface call
// Any exceptions will be thrown from the createTunTapInterface call
return tun;
}
//------------------------------------------------------------------------------
static const JNINativeMethod gMethods[] = {
{"jniCreateTun", "(Ljava/lang/String;)I", (void*)create},
{"jniCreateTunTap", "(ZLjava/lang/String;)I", (void*)create},
};
int register_android_server_TestNetworkService(JNIEnv* env) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment