| /* |
| * 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 <jni.h> |
| #include <nativehelper/JNIHelp.h> |
| #include <nativehelper/scoped_utf_chars.h> |
| #include <tcutils/tcutils.h> |
| |
| 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 add dev .. ingress prio .. protocol .. matchall \ |
| // action police rate .. burst .. conform-exceed pipe/continue \ |
| // action bpf object-pinned .. \ |
| // drop |
| static void com_android_net_module_util_TcUtils_tcFilterAddDevIngressPolice( |
| JNIEnv *env, jobject clazz, jint ifIndex, jshort prio, jshort proto, |
| jint rateInBytesPerSec, jstring bpfProgPath) { |
| ScopedUtfChars pathname(env, bpfProgPath); |
| int error = tcAddIngressPoliceFilter(ifIndex, prio, proto, rateInBytesPerSec, |
| pathname.c_str()); |
| if (error) { |
| throwIOException(env, |
| "com_android_net_module_util_TcUtils_" |
| "tcFilterAddDevIngressPolice 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}, |
| {"tcFilterAddDevIngressPolice", "(ISSILjava/lang/String;)V", |
| (void *)com_android_net_module_util_TcUtils_tcFilterAddDevIngressPolice}, |
| {"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 |