[CLATJ#9] ClatCoordinator: open tun interface
Open the v4-... tun interface for clat. The native function is moved from netd to jni. Bug: 212345928 Test: flash and boot Run "atest ClatCoordinatorTest" in a followup commit. Change-Id: I3f3c587275125ce3fc7481006947211f17dbb2d4
This commit is contained in:
@@ -15,7 +15,11 @@
|
||||
*/
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <fcntl.h>
|
||||
#include <linux/if_tun.h>
|
||||
#include <linux/ioctl.h>
|
||||
#include <nativehelper/JNIHelp.h>
|
||||
#include <net/if.h>
|
||||
|
||||
#include <netjniutils/netjniutils.h>
|
||||
|
||||
@@ -92,6 +96,34 @@ jstring com_android_server_connectivity_ClatCoordinator_generateIpv6Address(
|
||||
return env->NewStringUTF(addrstr);
|
||||
}
|
||||
|
||||
static jint com_android_server_connectivity_ClatCoordinator_createTunInterface(JNIEnv* env,
|
||||
jobject clazz,
|
||||
jstring tuniface) {
|
||||
ScopedUtfChars v4interface(env, tuniface);
|
||||
|
||||
// open the tun device in non blocking mode as required by clatd
|
||||
jint fd = open("/dev/net/tun", O_RDWR | O_NONBLOCK | O_CLOEXEC);
|
||||
if (fd == -1) {
|
||||
jniThrowExceptionFmt(env, "java/io/IOException", "open tun device failed (%s)",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct ifreq ifr = {
|
||||
.ifr_flags = IFF_TUN,
|
||||
};
|
||||
strlcpy(ifr.ifr_name, v4interface.c_str(), sizeof(ifr.ifr_name));
|
||||
|
||||
if (ioctl(fd, TUNSETIFF, &ifr, sizeof(ifr))) {
|
||||
close(fd);
|
||||
jniThrowExceptionFmt(env, "java/io/IOException", "ioctl(TUNSETIFF) failed (%s)",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
/*
|
||||
* JNI registration.
|
||||
*/
|
||||
@@ -102,6 +134,8 @@ static const JNINativeMethod gMethods[] = {
|
||||
{"generateIpv6Address",
|
||||
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
|
||||
(void*)com_android_server_connectivity_ClatCoordinator_generateIpv6Address},
|
||||
{"createTunInterface", "(Ljava/lang/String;)I",
|
||||
(void*)com_android_server_connectivity_ClatCoordinator_createTunInterface},
|
||||
};
|
||||
|
||||
int register_android_server_connectivity_ClatCoordinator(JNIEnv* env) {
|
||||
|
||||
@@ -20,6 +20,10 @@ import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.net.INetd;
|
||||
import android.net.IpPrefix;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceSpecificException;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
@@ -33,6 +37,9 @@ import java.io.IOException;
|
||||
public class ClatCoordinator {
|
||||
private static final String TAG = ClatCoordinator.class.getSimpleName();
|
||||
|
||||
// This must match the interface prefix in clatd.c.
|
||||
private static final String CLAT_PREFIX = "v4-";
|
||||
|
||||
// For historical reasons, start with 192.0.0.4, and after that, use all subsequent addresses
|
||||
// in 192.0.0.0/29 (RFC 7335).
|
||||
@VisibleForTesting
|
||||
@@ -58,6 +65,21 @@ public class ClatCoordinator {
|
||||
@NonNull
|
||||
public abstract INetd getNetd();
|
||||
|
||||
/**
|
||||
* @see ParcelFileDescriptor#adoptFd(int).
|
||||
*/
|
||||
@NonNull
|
||||
public ParcelFileDescriptor adoptFd(int fd) {
|
||||
return ParcelFileDescriptor.adoptFd(fd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create tun interface for a given interface name.
|
||||
*/
|
||||
public int jniCreateTunInterface(@NonNull String tuniface) throws IOException {
|
||||
return createTunInterface(tuniface);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pick an IPv4 address for clat.
|
||||
*/
|
||||
@@ -109,6 +131,23 @@ public class ClatCoordinator {
|
||||
throw new IOException("no IPv6 addresses were available for clat: " + e);
|
||||
}
|
||||
|
||||
// [3] Open, configure and bring up the tun interface.
|
||||
// Create the v4-... tun interface.
|
||||
final String tunIface = CLAT_PREFIX + iface;
|
||||
final ParcelFileDescriptor tunFd;
|
||||
try {
|
||||
tunFd = mDeps.adoptFd(mDeps.jniCreateTunInterface(tunIface));
|
||||
} catch (IOException e) {
|
||||
throw new IOException("Create tun interface " + tunIface + " failed: " + e);
|
||||
}
|
||||
|
||||
// disable IPv6 on it - failing to do so is not a critical error
|
||||
try {
|
||||
mNetd.interfaceSetEnableIPv6(tunIface, false /* enabled */);
|
||||
} catch (RemoteException | ServiceSpecificException e) {
|
||||
Log.e(TAG, "Disable IPv6 on " + tunIface + " failed: " + e);
|
||||
}
|
||||
|
||||
// TODO: start clatd and returns local xlat464 v6 address.
|
||||
return null;
|
||||
}
|
||||
@@ -117,4 +156,5 @@ public class ClatCoordinator {
|
||||
throws IOException;
|
||||
private static native String generateIpv6Address(String iface, String v4, String prefix64)
|
||||
throws IOException;
|
||||
private static native int createTunInterface(String tuniface) throws IOException;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user