tethering: offload: Netlink Req

Send netlink request over fd for offload config before
completing init sequence. Provides existing conntrack
entries to IPA. Resolves issue where there are NAT
misses in IPA due to IPA only having the conntrack
entries added after tethering starts.

Bug: 149109043
Test: OffloadHardwareInterfaceTest
Change-Id: Iaf3e847e92f205b55f10fa85c17b9f3995d52099
This commit is contained in:
Tyler Wear
2020-03-25 16:04:32 -07:00
parent f4394e83f8
commit 6b94c31626
2 changed files with 72 additions and 0 deletions

View File

@@ -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();