Skip to content
Snippets Groups Projects
Commit ad2b78a5 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "tethering: offload: Netlink Req" into rvc-dev am: 0de458a8

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/11970745

Change-Id: I14944e318cea5792941dcf2cf14c12ff468a846c
parents 0982de0e 0de458a8
No related branches found
No related tags found
No related merge requests found
......@@ -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;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment