• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <jni.h>
18 #include <nativehelper/JNIHelp.h>
19 #include <nativehelper/scoped_utf_chars.h>
20 #include <tcutils/tcutils.h>
21 
22 namespace android {
23 
throwIOException(JNIEnv * env,const char * msg,int error)24 static void throwIOException(JNIEnv *env, const char *msg, int error) {
25   jniThrowExceptionFmt(env, "java/io/IOException", "%s: %s", msg,
26                        strerror(error));
27 }
28 
com_android_net_module_util_TcUtils_isEthernet(JNIEnv * env,jobject clazz,jstring iface)29 static jboolean com_android_net_module_util_TcUtils_isEthernet(JNIEnv *env,
30                                                                jobject clazz,
31                                                                jstring iface) {
32   ScopedUtfChars interface(env, iface);
33   bool result = false;
34   int error = isEthernet(interface.c_str(), result);
35   if (error) {
36     throwIOException(
37         env, "com_android_net_module_util_TcUtils_isEthernet error: ", -error);
38   }
39   // result is not touched when error is returned; leave false.
40   return result;
41 }
42 
43 // tc filter add dev .. in/egress prio 1 protocol ipv6/ip bpf object-pinned
44 // /sys/fs/bpf/... direct-action
com_android_net_module_util_TcUtils_tcFilterAddDevBpf(JNIEnv * env,jobject clazz,jint ifIndex,jboolean ingress,jshort prio,jshort proto,jstring bpfProgPath)45 static void com_android_net_module_util_TcUtils_tcFilterAddDevBpf(
46     JNIEnv *env, jobject clazz, jint ifIndex, jboolean ingress, jshort prio,
47     jshort proto, jstring bpfProgPath) {
48   ScopedUtfChars pathname(env, bpfProgPath);
49   int error = tcAddBpfFilter(ifIndex, ingress, prio, proto, pathname.c_str());
50   if (error) {
51     throwIOException(
52         env,
53         "com_android_net_module_util_TcUtils_tcFilterAddDevBpf error: ", -error);
54   }
55 }
56 
57 // tc filter add dev .. ingress prio .. protocol .. matchall \
58 //     action police rate .. burst .. conform-exceed pipe/continue \
59 //     action bpf object-pinned .. \
60 //     drop
com_android_net_module_util_TcUtils_tcFilterAddDevIngressPolice(JNIEnv * env,jobject clazz,jint ifIndex,jshort prio,jshort proto,jint rateInBytesPerSec,jstring bpfProgPath)61 static void com_android_net_module_util_TcUtils_tcFilterAddDevIngressPolice(
62     JNIEnv *env, jobject clazz, jint ifIndex, jshort prio, jshort proto,
63     jint rateInBytesPerSec, jstring bpfProgPath) {
64   ScopedUtfChars pathname(env, bpfProgPath);
65   int error = tcAddIngressPoliceFilter(ifIndex, prio, proto, rateInBytesPerSec,
66                                        pathname.c_str());
67   if (error) {
68     throwIOException(env,
69                      "com_android_net_module_util_TcUtils_"
70                      "tcFilterAddDevIngressPolice error: ",
71                      -error);
72   }
73 }
74 
75 // tc filter del dev .. in/egress prio .. protocol ..
com_android_net_module_util_TcUtils_tcFilterDelDev(JNIEnv * env,jobject clazz,jint ifIndex,jboolean ingress,jshort prio,jshort proto)76 static void com_android_net_module_util_TcUtils_tcFilterDelDev(
77     JNIEnv *env, jobject clazz, jint ifIndex, jboolean ingress, jshort prio,
78     jshort proto) {
79   int error = tcDeleteFilter(ifIndex, ingress, prio, proto);
80   if (error) {
81     throwIOException(
82         env,
83         "com_android_net_module_util_TcUtils_tcFilterDelDev error: ", -error);
84   }
85 }
86 
87 // tc qdisc add dev .. clsact
com_android_net_module_util_TcUtils_tcQdiscAddDevClsact(JNIEnv * env,jobject clazz,jint ifIndex)88 static void com_android_net_module_util_TcUtils_tcQdiscAddDevClsact(JNIEnv *env,
89                                                                     jobject clazz,
90                                                                     jint ifIndex) {
91   int error = tcAddQdiscClsact(ifIndex);
92   if (error) {
93     throwIOException(
94         env,
95         "com_android_net_module_util_TcUtils_tcQdiscAddDevClsact error: ", -error);
96   }
97 }
98 
99 /*
100  * JNI registration.
101  */
102 static const JNINativeMethod gMethods[] = {
103     /* name, signature, funcPtr */
104     {"isEthernet", "(Ljava/lang/String;)Z",
105      (void *)com_android_net_module_util_TcUtils_isEthernet},
106     {"tcFilterAddDevBpf", "(IZSSLjava/lang/String;)V",
107      (void *)com_android_net_module_util_TcUtils_tcFilterAddDevBpf},
108     {"tcFilterAddDevIngressPolice", "(ISSILjava/lang/String;)V",
109      (void *)com_android_net_module_util_TcUtils_tcFilterAddDevIngressPolice},
110     {"tcFilterDelDev", "(IZSS)V",
111      (void *)com_android_net_module_util_TcUtils_tcFilterDelDev},
112     {"tcQdiscAddDevClsact", "(I)V",
113      (void *)com_android_net_module_util_TcUtils_tcQdiscAddDevClsact},
114 };
115 
register_com_android_net_module_util_TcUtils(JNIEnv * env,char const * class_name)116 int register_com_android_net_module_util_TcUtils(JNIEnv *env,
117                                                  char const *class_name) {
118   return jniRegisterNativeMethods(env, class_name, gMethods, NELEM(gMethods));
119 }
120 
121 }; // namespace android
122