diff --git a/service/jni/com_android_server_connectivity_ClatCoordinator.cpp b/service/jni/com_android_server_connectivity_ClatCoordinator.cpp index c658464286..562b1a2787 100644 --- a/service/jni/com_android_server_connectivity_ClatCoordinator.cpp +++ b/service/jni/com_android_server_connectivity_ClatCoordinator.cpp @@ -26,6 +26,9 @@ #include "libclat/clatutils.h" #include "nativehelper/scoped_utf_chars.h" +// Sync from system/netd/include/netid_client.h +#define MARK_UNSET 0u + namespace android { static void throwIOException(JNIEnv* env, const char* msg, int error) { jniThrowExceptionFmt(env, "java/io/IOException", "%s: %s", msg, strerror(error)); @@ -161,6 +164,25 @@ static jint com_android_server_connectivity_ClatCoordinator_openPacketSocket(JNI return sock; } +static jint com_android_server_connectivity_ClatCoordinator_openRawSocket6(JNIEnv* env, + jobject clazz, + jint mark) { + int sock = socket(AF_INET6, SOCK_RAW | SOCK_NONBLOCK | SOCK_CLOEXEC, IPPROTO_RAW); + if (sock < 0) { + throwIOException(env, "raw socket failed", errno); + return -1; + } + + // TODO: check the mark validation + if (mark != MARK_UNSET && setsockopt(sock, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) < 0) { + throwIOException(env, "could not set mark on raw socket", errno); + close(sock); + return -1; + } + + return sock; +} + /* * JNI registration. */ @@ -177,6 +199,8 @@ static const JNINativeMethod gMethods[] = { (void*)com_android_server_connectivity_ClatCoordinator_detectMtu}, {"openPacketSocket", "()I", (void*)com_android_server_connectivity_ClatCoordinator_openPacketSocket}, + {"openRawSocket6", "(I)I", + (void*)com_android_server_connectivity_ClatCoordinator_openRawSocket6}, }; int register_android_server_connectivity_ClatCoordinator(JNIEnv* env) { diff --git a/service/src/com/android/server/connectivity/ClatCoordinator.java b/service/src/com/android/server/connectivity/ClatCoordinator.java index bc635ed866..cf956c59e3 100644 --- a/service/src/com/android/server/connectivity/ClatCoordinator.java +++ b/service/src/com/android/server/connectivity/ClatCoordinator.java @@ -128,6 +128,13 @@ public class ClatCoordinator { public int jniOpenPacketSocket() throws IOException { return openPacketSocket(); } + + /** + * Open IPv6 raw socket and set SO_MARK. + */ + public int jniOpenRawSocket6(int mark) throws IOException { + return openRawSocket6(mark); + } } @VisibleForTesting @@ -241,6 +248,16 @@ public class ClatCoordinator { throw new IOException("Open packet socket failed: " + e); } + // Opens a raw socket with a given fwmark to send IPv6 packets in clatd. + final ParcelFileDescriptor writeSock6; + try { + // Use a JNI call to get native file descriptor instead of Os.socket(). See above + // reason why we use jniOpenPacketSocket6(). + writeSock6 = mDeps.adoptFd(mDeps.jniOpenRawSocket6(fwmark)); + } catch (IOException e) { + throw new IOException("Open raw socket failed: " + e); + } + // TODO: start clatd and returns local xlat464 v6 address. return null; } @@ -253,4 +270,5 @@ public class ClatCoordinator { private static native int detectMtu(String platSubnet, int platSuffix, int mark) throws IOException; private static native int openPacketSocket() throws IOException; + private static native int openRawSocket6(int mark) throws IOException; }