[CLATJ#19] ClatdCoordinator: configure bpf for clat

Configure eBPF offload at clat starting if possible.

Bug: 212345928
Test: connect to ipv6 only network and check bpf entries
$adb shell dumpsys netd --short | grep Clat -A10
  ClatdController
    Trackers: iif[iface] nat64Prefix v6Addr -> v4Addr v4iif[v4iface] [fwmark]
    BPF ingress map: iif(iface) nat64Prefix v6Addr -> v4Addr oif(iface)
      47(wlan0) 64:ff9b::/96 2a00:79e1:abc:6f02:b7aa:ff3c:9220:595c -> 192.0.0.4 52(v4-wlan0)
    BPF egress map: iif(iface) v4Addr -> v6Addr nat64Prefix oif(iface)
      52(v4-wlan0) 192.0.0.4 -> 2a00:79e1:abc:6f02:b7aa:ff3c:9220:595c 64:ff9b::/96 47(wlan0) ether

Change-Id: I8ff77a2e3e86bfe6dbf43f4181414e444ba0da32
This commit is contained in:
Hungming Chen
2022-01-16 14:47:52 +08:00
parent 8ebdb6f1fe
commit b1d3ccbeb6
3 changed files with 91 additions and 0 deletions

View File

@@ -65,6 +65,7 @@ cc_library_shared {
"libbase_headers", "libbase_headers",
], ],
static_libs: [ static_libs: [
"libbase",
"libclat", "libclat",
"libip_checksum", "libip_checksum",
"libnetjniutils", "libnetjniutils",

View File

@@ -19,17 +19,22 @@
#include <fcntl.h> #include <fcntl.h>
#include <linux/if_tun.h> #include <linux/if_tun.h>
#include <linux/ioctl.h> #include <linux/ioctl.h>
#include <log/log.h>
#include <nativehelper/JNIHelp.h> #include <nativehelper/JNIHelp.h>
#include <net/if.h> #include <net/if.h>
#include <string>
#include <netjniutils/netjniutils.h> #include <netjniutils/netjniutils.h>
#include "libclat/bpfhelper.h"
#include "libclat/clatutils.h" #include "libclat/clatutils.h"
#include "nativehelper/scoped_utf_chars.h" #include "nativehelper/scoped_utf_chars.h"
// Sync from system/netd/include/netid_client.h // Sync from system/netd/include/netid_client.h
#define MARK_UNSET 0u #define MARK_UNSET 0u
#define DEVICEPREFIX "v4-"
namespace android { namespace android {
static void throwIOException(JNIEnv* env, const char* msg, int error) { static void throwIOException(JNIEnv* env, const char* msg, int error) {
jniThrowExceptionFmt(env, "java/io/IOException", "%s: %s", msg, strerror(error)); jniThrowExceptionFmt(env, "java/io/IOException", "%s: %s", msg, strerror(error));
@@ -237,6 +242,67 @@ static void com_android_server_connectivity_ClatCoordinator_configurePacketSocke
} }
} }
int initTracker(const std::string& iface, const std::string& pfx96, const std::string& v4,
const std::string& v6, net::clat::ClatdTracker* output) {
strlcpy(output->iface, iface.c_str(), sizeof(output->iface));
output->ifIndex = if_nametoindex(iface.c_str());
if (output->ifIndex == 0) {
ALOGE("interface %s not found", output->iface);
return -1;
}
unsigned len = snprintf(output->v4iface, sizeof(output->v4iface),
"%s%s", DEVICEPREFIX, iface.c_str());
if (len >= sizeof(output->v4iface)) {
ALOGE("interface name too long '%s'", output->v4iface);
return -1;
}
output->v4ifIndex = if_nametoindex(output->v4iface);
if (output->v4ifIndex == 0) {
ALOGE("v4-interface %s not found", output->v4iface);
return -1;
}
if (!inet_pton(AF_INET6, pfx96.c_str(), &output->pfx96)) {
ALOGE("invalid IPv6 address specified for plat prefix: %s", pfx96.c_str());
return -1;
}
if (!inet_pton(AF_INET, v4.c_str(), &output->v4)) {
ALOGE("Invalid IPv4 address %s", v4.c_str());
return -1;
}
if (!inet_pton(AF_INET6, v6.c_str(), &output->v6)) {
ALOGE("Invalid source address %s", v6.c_str());
return -1;
}
return 0;
}
// TODO: fork clatd and rename to .._startClatd.
static jint com_android_server_connectivity_ClatCoordinator_maybeStartBpf(
JNIEnv* env, jobject clazz, jobject tunJavaFd, jobject readSockJavaFd,
jobject writeSockJavaFd, jstring iface, jstring pfx96, jstring v4, jstring v6) {
ScopedUtfChars ifaceStr(env, iface);
ScopedUtfChars pfx96Str(env, pfx96);
ScopedUtfChars v4Str(env, v4);
ScopedUtfChars v6Str(env, v6);
// Start BPF if any
if (!net::clat::initMaps()) {
net::clat::ClatdTracker tracker = {};
if (!initTracker(ifaceStr.c_str(), pfx96Str.c_str(), v4Str.c_str(), v6Str.c_str(),
&tracker)) {
net::clat::maybeStartBpf(tracker);
}
}
return 0; // TODO: return forked clatd pid.
}
/* /*
* JNI registration. * JNI registration.
*/ */
@@ -259,6 +325,10 @@ static const JNINativeMethod gMethods[] = {
(void*)com_android_server_connectivity_ClatCoordinator_addAnycastSetsockopt}, (void*)com_android_server_connectivity_ClatCoordinator_addAnycastSetsockopt},
{"native_configurePacketSocket", "(Ljava/io/FileDescriptor;Ljava/lang/String;I)V", {"native_configurePacketSocket", "(Ljava/io/FileDescriptor;Ljava/lang/String;I)V",
(void*)com_android_server_connectivity_ClatCoordinator_configurePacketSocket}, (void*)com_android_server_connectivity_ClatCoordinator_configurePacketSocket},
{"native_maybeStartBpf",
"(Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Ljava/lang/"
"String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I",
(void*)com_android_server_connectivity_ClatCoordinator_maybeStartBpf},
}; };
int register_android_server_connectivity_ClatCoordinator(JNIEnv* env) { int register_android_server_connectivity_ClatCoordinator(JNIEnv* env) {

View File

@@ -162,6 +162,15 @@ public class ClatCoordinator {
throws IOException { throws IOException {
native_configurePacketSocket(sock, v6, ifindex); native_configurePacketSocket(sock, v6, ifindex);
} }
/**
* Maybe start bpf.
*/
public int maybeStartBpf(@NonNull FileDescriptor tunfd, @NonNull FileDescriptor readsock6,
@NonNull FileDescriptor writesock6, @NonNull String iface, @NonNull String pfx96,
@NonNull String v4, @NonNull String v6) throws IOException {
return native_maybeStartBpf(tunfd, readsock6, writesock6, iface, pfx96, v4, v6);
}
} }
@VisibleForTesting @VisibleForTesting
@@ -304,6 +313,14 @@ public class ClatCoordinator {
throw new IOException("configure packet socket failed: " + e); throw new IOException("configure packet socket failed: " + e);
} }
// [5] Maybe start bpf.
try {
mDeps.maybeStartBpf(tunFd.getFileDescriptor(), readSock6.getFileDescriptor(),
writeSock6.getFileDescriptor(), iface, pfx96, v4, v6);
} catch (IOException e) {
throw new IOException("Error start bpf on " + iface + ": " + e);
}
// TODO: start clatd and returns local xlat464 v6 address. // TODO: start clatd and returns local xlat464 v6 address.
return null; return null;
} }
@@ -321,4 +338,7 @@ public class ClatCoordinator {
int ifindex) throws IOException; int ifindex) throws IOException;
private static native void native_configurePacketSocket(FileDescriptor sock, String v6, private static native void native_configurePacketSocket(FileDescriptor sock, String v6,
int ifindex) throws IOException; int ifindex) throws IOException;
private static native int native_maybeStartBpf(FileDescriptor tunfd, FileDescriptor readsock6,
FileDescriptor writesock6, String iface, String pfx96, String v4, String v6)
throws IOException;
} }