diff --git a/staticlibs/native/bpfmapjni/Android.bp b/staticlibs/native/bpfmapjni/Android.bp index b7af22d335..8d3c90b0a5 100644 --- a/staticlibs/native/bpfmapjni/Android.bp +++ b/staticlibs/native/bpfmapjni/Android.bp @@ -18,7 +18,10 @@ package { cc_library_static { name: "libnet_utils_device_common_bpfjni", - srcs: ["com_android_net_module_util_BpfMap.cpp"], + srcs: [ + "com_android_net_module_util_BpfMap.cpp", + "com_android_net_module_util_TcUtils.cpp", + ], header_libs: [ "bpf_syscall_wrappers", "jni_headers", @@ -27,6 +30,9 @@ cc_library_static { "liblog", "libnativehelper_compat_libc++", ], + static_libs: [ + "libtcutils", + ], cflags: [ "-Wall", "-Werror", diff --git a/staticlibs/native/bpfmapjni/com_android_net_module_util_TcUtils.cpp b/staticlibs/native/bpfmapjni/com_android_net_module_util_TcUtils.cpp new file mode 100644 index 0000000000..e5a3668527 --- /dev/null +++ b/staticlibs/native/bpfmapjni/com_android_net_module_util_TcUtils.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2022 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. + */ + +#include +#include +#include +#include + +namespace android { + +static void throwIOException(JNIEnv *env, const char *msg, int error) { + jniThrowExceptionFmt(env, "java/io/IOException", "%s: %s", msg, + strerror(error)); +} + +static jboolean com_android_net_module_util_TcUtils_isEthernet(JNIEnv *env, + jobject clazz, + jstring iface) { + ScopedUtfChars interface(env, iface); + bool result = false; + int error = isEthernet(interface.c_str(), result); + if (error) { + throwIOException( + env, "com_android_net_module_util_TcUtils_isEthernet error: ", error); + } + // result is not touched when error is returned; leave false. + return result; +} + +// tc filter add dev .. in/egress prio 1 protocol ipv6/ip bpf object-pinned +// /sys/fs/bpf/... direct-action +static void com_android_net_module_util_TcUtils_tcFilterAddDevBpf( + JNIEnv *env, jobject clazz, jint ifIndex, jboolean ingress, jshort prio, + jshort proto, jstring bpfProgPath) { + ScopedUtfChars pathname(env, bpfProgPath); + int error = tcAddBpfFilter(ifIndex, ingress, prio, proto, pathname.c_str()); + if (error) { + throwIOException( + env, + "com_android_net_module_util_TcUtils_tcFilterAddDevBpf error: ", error); + } +} + +// tc filter del dev .. in/egress prio .. protocol .. +static void com_android_net_module_util_TcUtils_tcFilterDelDev( + JNIEnv *env, jobject clazz, jint ifIndex, jboolean ingress, jshort prio, + jshort proto) { + int error = tcDeleteFilter(ifIndex, ingress, prio, proto); + if (error) { + throwIOException( + env, + "com_android_net_module_util_TcUtils_tcFilterDelDev error: ", error); + } +} + +/* + * JNI registration. + */ +static const JNINativeMethod gMethods[] = { + /* name, signature, funcPtr */ + {"isEthernet", "(Ljava/lang/String;)Z", + (void *)com_android_net_module_util_TcUtils_isEthernet}, + {"tcFilterAddDevBpf", "(IZSSLjava/lang/String;)V", + (void *)com_android_net_module_util_TcUtils_tcFilterAddDevBpf}, + {"tcFilterDelDev", "(IZSS)V", + (void *)com_android_net_module_util_TcUtils_tcFilterDelDev}, +}; + +int register_com_android_net_module_util_TcUtils(JNIEnv *env, + char const *class_name) { + return jniRegisterNativeMethods(env, class_name, gMethods, NELEM(gMethods)); +} + +}; // namespace android