Snap for 6626121 from 73113a69970941d644291b75b173ff8d18eb2086 to rvc-release
Change-Id: I91c888d0ca97e8297c7adbe19150b0dabd9f181a
This commit is contained in:
@@ -171,6 +171,14 @@ public class TetheringManager {
|
||||
*/
|
||||
public static final int TETHERING_ETHERNET = 5;
|
||||
|
||||
/**
|
||||
* WIGIG tethering type. Use a separate type to prevent
|
||||
* conflicts with TETHERING_WIFI
|
||||
* This type is only used internally by the tethering module
|
||||
* @hide
|
||||
*/
|
||||
public static final int TETHERING_WIGIG = 6;
|
||||
|
||||
/** @hide */
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(value = {
|
||||
|
||||
@@ -42,6 +42,13 @@
|
||||
<item>"softap\\d"</item>
|
||||
</string-array>
|
||||
|
||||
<!-- List of regexpressions describing the interface (if any) that represent tetherable
|
||||
WiGig interfaces. If the device doesn't want to support tethering over WiGig this
|
||||
should be empty. An example would be "wigig\\d" -->
|
||||
<string-array translatable="false" name="config_tether_wigig_regexs">
|
||||
<item>"wigig\\d"</item>
|
||||
</string-array>
|
||||
|
||||
<!-- List of regexpressions describing the interface (if any) that represent tetherable
|
||||
Wifi P2P interfaces. If the device doesn't want to support tethering over Wifi P2p this
|
||||
should be empty. An example would be "p2p-p2p\\d-.*" -->
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
<item type="array" name="config_tether_usb_regexs"/>
|
||||
<item type="array" name="config_tether_ncm_regexs" />
|
||||
<item type="array" name="config_tether_wifi_regexs"/>
|
||||
<item type="array" name="config_tether_wigig_regexs"/>
|
||||
<item type="array" name="config_tether_wifi_p2p_regexs"/>
|
||||
<item type="array" name="config_tether_bluetooth_regexs"/>
|
||||
<item type="array" name="config_tether_dhcp_range"/>
|
||||
|
||||
@@ -617,7 +617,8 @@ public class IpServer extends StateMachine {
|
||||
final Boolean setIfaceUp;
|
||||
if (mInterfaceType == TetheringManager.TETHERING_WIFI
|
||||
|| mInterfaceType == TetheringManager.TETHERING_WIFI_P2P
|
||||
|| mInterfaceType == TetheringManager.TETHERING_ETHERNET) {
|
||||
|| mInterfaceType == TetheringManager.TETHERING_ETHERNET
|
||||
|| mInterfaceType == TetheringManager.TETHERING_WIGIG) {
|
||||
// The WiFi and Ethernet stack has ownership of the interface up/down state.
|
||||
// It is unclear whether the Bluetooth or USB stacks will manage their own
|
||||
// state.
|
||||
|
||||
@@ -16,8 +16,11 @@
|
||||
|
||||
package com.android.networkstack.tethering;
|
||||
|
||||
import static android.net.netlink.StructNlMsgHdr.NLM_F_DUMP;
|
||||
import static android.net.netlink.StructNlMsgHdr.NLM_F_REQUEST;
|
||||
import static android.net.util.TetheringUtils.uint16;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.hardware.tetheroffload.config.V1_0.IOffloadConfig;
|
||||
import android.hardware.tetheroffload.control.V1_0.IOffloadControl;
|
||||
import android.hardware.tetheroffload.control.V1_0.ITetheringOffloadCallback;
|
||||
@@ -25,6 +28,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.netlink.NetlinkSocket;
|
||||
import android.net.netlink.StructNlMsgHdr;
|
||||
import android.net.util.SharedLog;
|
||||
import android.net.util.SocketUtils;
|
||||
import android.os.Handler;
|
||||
@@ -37,9 +41,11 @@ import android.system.OsConstants;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.io.IOException;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.SocketException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
@@ -63,6 +69,11 @@ public class OffloadHardwareInterface {
|
||||
private static final int NF_NETLINK_CONNTRACK_NEW = 1;
|
||||
private static final int NF_NETLINK_CONNTRACK_UPDATE = 2;
|
||||
private static final int NF_NETLINK_CONNTRACK_DESTROY = 4;
|
||||
// Reference libnetfilter_conntrack/linux_nfnetlink_conntrack.h
|
||||
public static final short NFNL_SUBSYS_CTNETLINK = 1;
|
||||
public static final short IPCTNL_MSG_CT_GET = 1;
|
||||
|
||||
private final long NETLINK_MESSAGE_TIMEOUT_MS = 500;
|
||||
|
||||
private final Handler mHandler;
|
||||
private final SharedLog mLog;
|
||||
@@ -226,6 +237,9 @@ public class OffloadHardwareInterface {
|
||||
NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY);
|
||||
if (h1 == null) return false;
|
||||
|
||||
sendNetlinkMessage(h1, (short) ((NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_GET),
|
||||
(short) (NLM_F_REQUEST | NLM_F_DUMP));
|
||||
|
||||
final NativeHandle h2 = mDeps.createConntrackSocket(
|
||||
NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY);
|
||||
if (h2 == null) {
|
||||
@@ -252,6 +266,25 @@ public class OffloadHardwareInterface {
|
||||
return results.mSuccess;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public void sendNetlinkMessage(@NonNull NativeHandle handle, short type, short flags) {
|
||||
final int length = StructNlMsgHdr.STRUCT_SIZE;
|
||||
final byte[] msg = new byte[length];
|
||||
final StructNlMsgHdr nlh = new StructNlMsgHdr();
|
||||
final ByteBuffer byteBuffer = ByteBuffer.wrap(msg);
|
||||
nlh.nlmsg_len = length;
|
||||
nlh.nlmsg_type = type;
|
||||
nlh.nlmsg_flags = flags;
|
||||
nlh.nlmsg_seq = 1;
|
||||
nlh.pack(byteBuffer);
|
||||
try {
|
||||
NetlinkSocket.sendMessage(handle.getFileDescriptor(), msg, 0 /* offset */, length,
|
||||
NETLINK_MESSAGE_TIMEOUT_MS);
|
||||
} catch (ErrnoException | InterruptedIOException e) {
|
||||
mLog.e("Unable to send netfilter message, error: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
private void closeFdInNativeHandle(final NativeHandle h) {
|
||||
try {
|
||||
h.close();
|
||||
|
||||
@@ -40,6 +40,7 @@ import static android.net.TetheringManager.TETHERING_NCM;
|
||||
import static android.net.TetheringManager.TETHERING_USB;
|
||||
import static android.net.TetheringManager.TETHERING_WIFI;
|
||||
import static android.net.TetheringManager.TETHERING_WIFI_P2P;
|
||||
import static android.net.TetheringManager.TETHERING_WIGIG;
|
||||
import static android.net.TetheringManager.TETHER_ERROR_INTERNAL_ERROR;
|
||||
import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
|
||||
import static android.net.TetheringManager.TETHER_ERROR_SERVICE_UNAVAIL;
|
||||
@@ -495,7 +496,8 @@ public class Tethering {
|
||||
if (up) {
|
||||
maybeTrackNewInterfaceLocked(iface);
|
||||
} else {
|
||||
if (ifaceNameToType(iface) == TETHERING_BLUETOOTH) {
|
||||
if (ifaceNameToType(iface) == TETHERING_BLUETOOTH
|
||||
|| ifaceNameToType(iface) == TETHERING_WIGIG) {
|
||||
stopTrackingInterfaceLocked(iface);
|
||||
} else {
|
||||
// Ignore usb0 down after enabling RNDIS.
|
||||
@@ -517,6 +519,8 @@ public class Tethering {
|
||||
|
||||
if (cfg.isWifi(iface)) {
|
||||
return TETHERING_WIFI;
|
||||
} else if (cfg.isWigig(iface)) {
|
||||
return TETHERING_WIGIG;
|
||||
} else if (cfg.isWifiP2p(iface)) {
|
||||
return TETHERING_WIFI_P2P;
|
||||
} else if (cfg.isUsb(iface)) {
|
||||
|
||||
@@ -92,6 +92,7 @@ public class TetheringConfiguration {
|
||||
|
||||
public final String[] tetherableUsbRegexs;
|
||||
public final String[] tetherableWifiRegexs;
|
||||
public final String[] tetherableWigigRegexs;
|
||||
public final String[] tetherableWifiP2pRegexs;
|
||||
public final String[] tetherableBluetoothRegexs;
|
||||
public final String[] tetherableNcmRegexs;
|
||||
@@ -125,6 +126,7 @@ public class TetheringConfiguration {
|
||||
// us an interface name. Careful consideration needs to be given to
|
||||
// implications for Settings and for provisioning checks.
|
||||
tetherableWifiRegexs = getResourceStringArray(res, R.array.config_tether_wifi_regexs);
|
||||
tetherableWigigRegexs = getResourceStringArray(res, R.array.config_tether_wigig_regexs);
|
||||
tetherableWifiP2pRegexs = getResourceStringArray(
|
||||
res, R.array.config_tether_wifi_p2p_regexs);
|
||||
tetherableBluetoothRegexs = getResourceStringArray(
|
||||
@@ -167,6 +169,11 @@ public class TetheringConfiguration {
|
||||
return matchesDownstreamRegexs(iface, tetherableWifiRegexs);
|
||||
}
|
||||
|
||||
/** Check whether input interface belong to wigig.*/
|
||||
public boolean isWigig(String iface) {
|
||||
return matchesDownstreamRegexs(iface, tetherableWigigRegexs);
|
||||
}
|
||||
|
||||
/** Check whether this interface is Wifi P2P interface. */
|
||||
public boolean isWifiP2p(String iface) {
|
||||
return matchesDownstreamRegexs(iface, tetherableWifiP2pRegexs);
|
||||
|
||||
@@ -17,13 +17,17 @@
|
||||
package com.android.networkstack.tethering;
|
||||
|
||||
import static android.net.util.TetheringUtils.uint16;
|
||||
import static android.system.OsConstants.SOCK_STREAM;
|
||||
import static android.system.OsConstants.AF_UNIX;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.hardware.tetheroffload.config.V1_0.IOffloadConfig;
|
||||
import android.hardware.tetheroffload.control.V1_0.IOffloadControl;
|
||||
@@ -31,11 +35,14 @@ import android.hardware.tetheroffload.control.V1_0.ITetheringOffloadCallback;
|
||||
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.netlink.StructNlMsgHdr;
|
||||
import android.net.util.SharedLog;
|
||||
import android.os.Handler;
|
||||
import android.os.NativeHandle;
|
||||
import android.os.test.TestLooper;
|
||||
import android.system.ErrnoException;
|
||||
import android.system.OsConstants;
|
||||
import android.system.Os;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
@@ -47,6 +54,9 @@ import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@@ -64,6 +74,10 @@ public final class OffloadHardwareInterfaceTest {
|
||||
@Mock private IOffloadControl mIOffloadControl;
|
||||
@Mock private NativeHandle mNativeHandle;
|
||||
|
||||
// Random values to test Netlink message.
|
||||
private static final short TEST_TYPE = 184;
|
||||
private static final short TEST_FLAGS = 263;
|
||||
|
||||
class MyDependencies extends OffloadHardwareInterface.Dependencies {
|
||||
MyDependencies(SharedLog log) {
|
||||
super(log);
|
||||
@@ -203,6 +217,31 @@ public final class OffloadHardwareInterfaceTest {
|
||||
eq(uint16(udpParams.dst.port)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNetlinkMessage() throws Exception {
|
||||
FileDescriptor writeSocket = new FileDescriptor();
|
||||
FileDescriptor readSocket = new FileDescriptor();
|
||||
try {
|
||||
Os.socketpair(AF_UNIX, SOCK_STREAM, 0, writeSocket, readSocket);
|
||||
} catch (ErrnoException e) {
|
||||
fail();
|
||||
return;
|
||||
}
|
||||
when(mNativeHandle.getFileDescriptor()).thenReturn(writeSocket);
|
||||
|
||||
mOffloadHw.sendNetlinkMessage(mNativeHandle, TEST_TYPE, TEST_FLAGS);
|
||||
|
||||
ByteBuffer buffer = ByteBuffer.allocate(StructNlMsgHdr.STRUCT_SIZE);
|
||||
int read = Os.read(readSocket, buffer);
|
||||
|
||||
buffer.flip();
|
||||
assertEquals(StructNlMsgHdr.STRUCT_SIZE, buffer.getInt());
|
||||
assertEquals(TEST_TYPE, buffer.getShort());
|
||||
assertEquals(TEST_FLAGS, buffer.getShort());
|
||||
assertEquals(1 /* seq */, buffer.getInt());
|
||||
assertEquals(0 /* pid */, buffer.getInt());
|
||||
}
|
||||
|
||||
private NatTimeoutUpdate buildNatTimeoutUpdate(final int proto) {
|
||||
final NatTimeoutUpdate params = new NatTimeoutUpdate();
|
||||
params.proto = proto;
|
||||
|
||||
Reference in New Issue
Block a user