Merge "tethering: offload: Netlink Req"
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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