diff options
author | markchien <markchien@google.com> | 2020-01-07 01:12:30 -0800 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2020-01-07 01:12:30 -0800 |
commit | 75b03696158a07acdc3ad35fdfd4cf818b16ddc3 (patch) | |
tree | 9752a71fd9fb301fae9b772532bc7b4e89ebe521 | |
parent | d913b9037a34a609fa718c5add45bfbbb76e8eb9 (diff) | |
parent | 3e16a10a3e8ba9512df4ebccc676b990d003212c (diff) | |
download | base-75b03696158a07acdc3ad35fdfd4cf818b16ddc3.tar.gz |
Merge "Change tetheroffloadjni to tetheringutilsjni"
am: 3e16a10a3e
Change-Id: I48207d95cf6f512ec038fb5dc9ba4009c01d676d
-rw-r--r-- | core/java/android/net/NetworkUtils.java | 7 | ||||
-rw-r--r-- | core/jni/android_net_NetUtils.cpp | 95 | ||||
-rw-r--r-- | packages/Tethering/Android.bp | 6 | ||||
-rw-r--r-- | packages/Tethering/jni/android_net_util_TetheringUtils.cpp (renamed from packages/Tethering/jni/com_android_server_connectivity_tethering_OffloadHardwareInterface.cpp) | 108 | ||||
-rw-r--r-- | packages/Tethering/src/android/net/ip/RouterAdvertisementDaemon.java | 3 | ||||
-rw-r--r-- | packages/Tethering/src/android/net/util/TetheringUtils.java | 42 | ||||
-rw-r--r-- | packages/Tethering/src/com/android/server/connectivity/tethering/OffloadHardwareInterface.java | 7 | ||||
-rw-r--r-- | packages/Tethering/src/com/android/server/connectivity/tethering/TetheringService.java | 1 |
8 files changed, 151 insertions, 118 deletions
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java index d0f54b4c7f2d..01cb9883564a 100644 --- a/core/java/android/net/NetworkUtils.java +++ b/core/java/android/net/NetworkUtils.java @@ -61,13 +61,6 @@ public class NetworkUtils { public static native void detachBPFFilter(FileDescriptor fd) throws SocketException; /** - * Configures a socket for receiving ICMPv6 router solicitations and sending advertisements. - * @param fd the socket's {@link FileDescriptor}. - * @param ifIndex the interface index. - */ - public native static void setupRaSocket(FileDescriptor fd, int ifIndex) throws SocketException; - - /** * Binds the current process to the network designated by {@code netId}. All sockets created * in the future (and not explicitly bound via a bound {@link SocketFactory} (see * {@link Network#getSocketFactory}) will be bound to this network. Note that if this diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp index 08aa1d97fa1c..ba7fe7ff8739 100644 --- a/core/jni/android_net_NetUtils.cpp +++ b/core/jni/android_net_NetUtils.cpp @@ -24,9 +24,7 @@ #include <linux/tcp.h> #include <net/if.h> #include <netinet/ether.h> -#include <netinet/icmp6.h> #include <netinet/ip.h> -#include <netinet/ip6.h> #include <netinet/udp.h> #include <android_runtime/AndroidRuntime.h> @@ -102,98 +100,6 @@ static void android_net_utils_detachBPFFilter(JNIEnv *env, jobject clazz, jobjec } } -static void android_net_utils_setupRaSocket(JNIEnv *env, jobject clazz, jobject javaFd, - jint ifIndex) -{ - static const int kLinkLocalHopLimit = 255; - - int fd = jniGetFDFromFileDescriptor(env, javaFd); - - // Set an ICMPv6 filter that only passes Router Solicitations. - struct icmp6_filter rs_only; - ICMP6_FILTER_SETBLOCKALL(&rs_only); - ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &rs_only); - socklen_t len = sizeof(rs_only); - if (setsockopt(fd, IPPROTO_ICMPV6, ICMP6_FILTER, &rs_only, len) != 0) { - jniThrowExceptionFmt(env, "java/net/SocketException", - "setsockopt(ICMP6_FILTER): %s", strerror(errno)); - return; - } - - // Most/all of the rest of these options can be set via Java code, but - // because we're here on account of setting an icmp6_filter go ahead - // and do it all natively for now. - // - // TODO: Consider moving these out to Java. - - // Set the multicast hoplimit to 255 (link-local only). - int hops = kLinkLocalHopLimit; - len = sizeof(hops); - if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hops, len) != 0) { - jniThrowExceptionFmt(env, "java/net/SocketException", - "setsockopt(IPV6_MULTICAST_HOPS): %s", strerror(errno)); - return; - } - - // Set the unicast hoplimit to 255 (link-local only). - hops = kLinkLocalHopLimit; - len = sizeof(hops); - if (setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &hops, len) != 0) { - jniThrowExceptionFmt(env, "java/net/SocketException", - "setsockopt(IPV6_UNICAST_HOPS): %s", strerror(errno)); - return; - } - - // Explicitly disable multicast loopback. - int off = 0; - len = sizeof(off); - if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &off, len) != 0) { - jniThrowExceptionFmt(env, "java/net/SocketException", - "setsockopt(IPV6_MULTICAST_LOOP): %s", strerror(errno)); - return; - } - - // Specify the IPv6 interface to use for outbound multicast. - len = sizeof(ifIndex); - if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifIndex, len) != 0) { - jniThrowExceptionFmt(env, "java/net/SocketException", - "setsockopt(IPV6_MULTICAST_IF): %s", strerror(errno)); - return; - } - - // Additional options to be considered: - // - IPV6_TCLASS - // - IPV6_RECVPKTINFO - // - IPV6_RECVHOPLIMIT - - // Bind to [::]. - const struct sockaddr_in6 sin6 = { - .sin6_family = AF_INET6, - .sin6_port = 0, - .sin6_flowinfo = 0, - .sin6_addr = IN6ADDR_ANY_INIT, - .sin6_scope_id = 0, - }; - auto sa = reinterpret_cast<const struct sockaddr *>(&sin6); - len = sizeof(sin6); - if (bind(fd, sa, len) != 0) { - jniThrowExceptionFmt(env, "java/net/SocketException", - "bind(IN6ADDR_ANY): %s", strerror(errno)); - return; - } - - // Join the all-routers multicast group, ff02::2%index. - struct ipv6_mreq all_rtrs = { - .ipv6mr_multiaddr = {{{0xff,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2}}}, - .ipv6mr_interface = ifIndex, - }; - len = sizeof(all_rtrs); - if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &all_rtrs, len) != 0) { - jniThrowExceptionFmt(env, "java/net/SocketException", - "setsockopt(IPV6_JOIN_GROUP): %s", strerror(errno)); - return; - } -} static jboolean android_net_utils_bindProcessToNetwork(JNIEnv *env, jobject thiz, jint netId) { @@ -370,7 +276,6 @@ static const JNINativeMethod gNetworkUtilMethods[] = { { "attachDropAllBPFFilter", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_attachDropAllBPFFilter }, { "detachBPFFilter", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_detachBPFFilter }, { "getTcpRepairWindow", "(Ljava/io/FileDescriptor;)Landroid/net/TcpRepairWindow;", (void*) android_net_utils_getTcpRepairWindow }, - { "setupRaSocket", "(Ljava/io/FileDescriptor;I)V", (void*) android_net_utils_setupRaSocket }, { "resNetworkSend", "(I[BII)Ljava/io/FileDescriptor;", (void*) android_net_utils_resNetworkSend }, { "resNetworkQuery", "(ILjava/lang/String;III)Ljava/io/FileDescriptor;", (void*) android_net_utils_resNetworkQuery }, { "resNetworkResult", "(Ljava/io/FileDescriptor;)Landroid/net/DnsResolver$DnsResponse;", (void*) android_net_utils_resNetworkResult }, diff --git a/packages/Tethering/Android.bp b/packages/Tethering/Android.bp index 08552cbfd394..596f62fad23e 100644 --- a/packages/Tethering/Android.bp +++ b/packages/Tethering/Android.bp @@ -45,9 +45,9 @@ android_library { // Due to b/143733063, APK can't access a jni lib that is in APEX (but not in the APK). cc_library { - name: "libtetheroffloadjni", + name: "libtetherutilsjni", srcs: [ - "jni/com_android_server_connectivity_tethering_OffloadHardwareInterface.cpp", + "jni/android_net_util_TetheringUtils.cpp", ], shared_libs: [ "libcgrouprc", @@ -87,7 +87,7 @@ java_defaults { "libcgrouprc", "libnativehelper_compat_libc++", "libvndksupport", - "libtetheroffloadjni", + "libtetherutilsjni", ], resource_dirs: [ "res", diff --git a/packages/Tethering/jni/com_android_server_connectivity_tethering_OffloadHardwareInterface.cpp b/packages/Tethering/jni/android_net_util_TetheringUtils.cpp index 663154a49048..1cf8f988432c 100644 --- a/packages/Tethering/jni/com_android_server_connectivity_tethering_OffloadHardwareInterface.cpp +++ b/packages/Tethering/jni/android_net_util_TetheringUtils.cpp @@ -19,13 +19,16 @@ #include <hidl/HidlSupport.h> #include <jni.h> #include <nativehelper/JNIHelp.h> +#include <nativehelper/ScopedUtfChars.h> #include <linux/netfilter/nfnetlink.h> #include <linux/netlink.h> +#include <net/if.h> +#include <netinet/icmp6.h> #include <sys/socket.h> #include <android-base/unique_fd.h> #include <android/hardware/tetheroffload/config/1.0/IOffloadConfig.h> -#define LOG_TAG "OffloadHardwareInterface" +#define LOG_TAG "TetheringUtils" #include <utils/Log.h> namespace android { @@ -87,7 +90,7 @@ hidl_handle handleFromFileDescriptor(base::unique_fd fd) { } // namespace -static jboolean android_server_connectivity_tethering_OffloadHardwareInterface_configOffload( +static jboolean android_net_util_configOffload( JNIEnv* /* env */) { sp<IOffloadConfig> configInterface = IOffloadConfig::getService(); if (configInterface.get() == nullptr) { @@ -130,18 +133,109 @@ static jboolean android_server_connectivity_tethering_OffloadHardwareInterface_c return rval; } +static void android_net_util_setupRaSocket(JNIEnv *env, jobject clazz, jobject javaFd, + jint ifIndex) +{ + static const int kLinkLocalHopLimit = 255; + + int fd = jniGetFDFromFileDescriptor(env, javaFd); + + // Set an ICMPv6 filter that only passes Router Solicitations. + struct icmp6_filter rs_only; + ICMP6_FILTER_SETBLOCKALL(&rs_only); + ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &rs_only); + socklen_t len = sizeof(rs_only); + if (setsockopt(fd, IPPROTO_ICMPV6, ICMP6_FILTER, &rs_only, len) != 0) { + jniThrowExceptionFmt(env, "java/net/SocketException", + "setsockopt(ICMP6_FILTER): %s", strerror(errno)); + return; + } + + // Most/all of the rest of these options can be set via Java code, but + // because we're here on account of setting an icmp6_filter go ahead + // and do it all natively for now. + + // Set the multicast hoplimit to 255 (link-local only). + int hops = kLinkLocalHopLimit; + len = sizeof(hops); + if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hops, len) != 0) { + jniThrowExceptionFmt(env, "java/net/SocketException", + "setsockopt(IPV6_MULTICAST_HOPS): %s", strerror(errno)); + return; + } + + // Set the unicast hoplimit to 255 (link-local only). + hops = kLinkLocalHopLimit; + len = sizeof(hops); + if (setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &hops, len) != 0) { + jniThrowExceptionFmt(env, "java/net/SocketException", + "setsockopt(IPV6_UNICAST_HOPS): %s", strerror(errno)); + return; + } + + // Explicitly disable multicast loopback. + int off = 0; + len = sizeof(off); + if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &off, len) != 0) { + jniThrowExceptionFmt(env, "java/net/SocketException", + "setsockopt(IPV6_MULTICAST_LOOP): %s", strerror(errno)); + return; + } + + // Specify the IPv6 interface to use for outbound multicast. + len = sizeof(ifIndex); + if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifIndex, len) != 0) { + jniThrowExceptionFmt(env, "java/net/SocketException", + "setsockopt(IPV6_MULTICAST_IF): %s", strerror(errno)); + return; + } + + // Additional options to be considered: + // - IPV6_TCLASS + // - IPV6_RECVPKTINFO + // - IPV6_RECVHOPLIMIT + + // Bind to [::]. + const struct sockaddr_in6 sin6 = { + .sin6_family = AF_INET6, + .sin6_port = 0, + .sin6_flowinfo = 0, + .sin6_addr = IN6ADDR_ANY_INIT, + .sin6_scope_id = 0, + }; + auto sa = reinterpret_cast<const struct sockaddr *>(&sin6); + len = sizeof(sin6); + if (bind(fd, sa, len) != 0) { + jniThrowExceptionFmt(env, "java/net/SocketException", + "bind(IN6ADDR_ANY): %s", strerror(errno)); + return; + } + + // Join the all-routers multicast group, ff02::2%index. + struct ipv6_mreq all_rtrs = { + .ipv6mr_multiaddr = {{{0xff,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2}}}, + .ipv6mr_interface = ifIndex, + }; + len = sizeof(all_rtrs); + if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &all_rtrs, len) != 0) { + jniThrowExceptionFmt(env, "java/net/SocketException", + "setsockopt(IPV6_JOIN_GROUP): %s", strerror(errno)); + return; + } +} + /* * JNI registration. */ static const JNINativeMethod gMethods[] = { /* name, signature, funcPtr */ - { "configOffload", "()Z", - (void*) android_server_connectivity_tethering_OffloadHardwareInterface_configOffload }, + { "configOffload", "()Z", (void*) android_net_util_configOffload }, + { "setupRaSocket", "(Ljava/io/FileDescriptor;I)V", (void*) android_net_util_setupRaSocket }, }; -int register_android_server_connectivity_tethering_OffloadHardwareInterface(JNIEnv* env) { +int register_android_net_util_TetheringUtils(JNIEnv* env) { return jniRegisterNativeMethods(env, - "com/android/server/connectivity/tethering/OffloadHardwareInterface", + "android/net/util/TetheringUtils", gMethods, NELEM(gMethods)); } @@ -152,7 +246,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void*) { return JNI_ERR; } - if (register_android_server_connectivity_tethering_OffloadHardwareInterface(env) < 0) { + if (register_android_net_util_TetheringUtils(env) < 0) { return JNI_ERR; } diff --git a/packages/Tethering/src/android/net/ip/RouterAdvertisementDaemon.java b/packages/Tethering/src/android/net/ip/RouterAdvertisementDaemon.java index 414741309ef0..4396cdb92621 100644 --- a/packages/Tethering/src/android/net/ip/RouterAdvertisementDaemon.java +++ b/packages/Tethering/src/android/net/ip/RouterAdvertisementDaemon.java @@ -30,6 +30,7 @@ import android.net.LinkAddress; import android.net.NetworkUtils; import android.net.TrafficStats; import android.net.util.InterfaceParams; +import android.net.util.TetheringUtils; import android.system.ErrnoException; import android.system.Os; import android.system.StructTimeval; @@ -613,7 +614,7 @@ public class RouterAdvertisementDaemon { mSocket, SOL_SOCKET, SO_SNDTIMEO, StructTimeval.fromMillis(send_timout_ms)); Os.setsockoptIfreq(mSocket, SOL_SOCKET, SO_BINDTODEVICE, mInterface.name); NetworkUtils.protectFromVpn(mSocket); - NetworkUtils.setupRaSocket(mSocket, mInterface.index); + TetheringUtils.setupRaSocket(mSocket, mInterface.index); } catch (ErrnoException | IOException e) { Log.e(TAG, "Failed to create RA daemon socket: " + e); return false; diff --git a/packages/Tethering/src/android/net/util/TetheringUtils.java b/packages/Tethering/src/android/net/util/TetheringUtils.java new file mode 100644 index 000000000000..2fb73ced8884 --- /dev/null +++ b/packages/Tethering/src/android/net/util/TetheringUtils.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2019 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. + */ +package android.net.util; + +import java.io.FileDescriptor; +import java.net.SocketException; + +/** + * Native methods for tethering utilization. + * + * {@hide} + */ +public class TetheringUtils { + + /** + * Offload management process need to know conntrack rules to support NAT, but it may not have + * permission to create netlink netfilter sockets. Create two netlink netfilter sockets and + * share them with offload management process. + */ + public static native boolean configOffload(); + + /** + * Configures a socket for receiving ICMPv6 router solicitations and sending advertisements. + * @param fd the socket's {@link FileDescriptor}. + * @param ifIndex the interface index. + */ + public static native void setupRaSocket(FileDescriptor fd, int ifIndex) + throws SocketException; +} diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadHardwareInterface.java b/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadHardwareInterface.java index 00a677338b1b..85164edf3c5b 100644 --- a/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadHardwareInterface.java +++ b/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadHardwareInterface.java @@ -24,6 +24,7 @@ import android.hardware.tetheroffload.control.V1_0.NatTimeoutUpdate; import android.hardware.tetheroffload.control.V1_0.NetworkProtocol; import android.hardware.tetheroffload.control.V1_0.OffloadCallbackEvent; import android.net.util.SharedLog; +import android.net.util.TetheringUtils; import android.os.Handler; import android.os.RemoteException; import android.system.OsConstants; @@ -47,8 +48,6 @@ public class OffloadHardwareInterface { private static final String NO_IPV4_ADDRESS = ""; private static final String NO_IPV4_GATEWAY = ""; - private static native boolean configOffload(); - private final Handler mHandler; private final SharedLog mLog; private IOffloadControl mOffloadControl; @@ -107,8 +106,6 @@ public class OffloadHardwareInterface { public OffloadHardwareInterface(Handler h, SharedLog log) { mHandler = h; mLog = log.forSubComponent(TAG); - - System.loadLibrary("tetheroffloadjni"); } /** Get default value indicating whether offload is supported. */ @@ -118,7 +115,7 @@ public class OffloadHardwareInterface { /** Configure offload management process. */ public boolean initOffloadConfig() { - return configOffload(); + return TetheringUtils.configOffload(); } /** Initialize the tethering offload HAL. */ diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringService.java b/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringService.java index ba30845e6348..1d5998680287 100644 --- a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringService.java +++ b/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringService.java @@ -84,6 +84,7 @@ public class TetheringService extends Service { */ @VisibleForTesting public Tethering makeTethering(TetheringDependencies deps) { + System.loadLibrary("tetherutilsjni"); return new Tethering(deps); } |