From bc8517843581eab82e01c937b1c627ee68c24ffd Mon Sep 17 00:00:00 2001 From: Hungming Chen Date: Thu, 19 Aug 2021 21:44:58 +0800 Subject: [PATCH] bpf: don't offload IPv4 packets with TCP port 21 (ftp) and 1723 (pptp) Bypass the IPv4 TCP packets with port 21 (ftp) and 1723 (pptp) from BPF offload because these packets need the netfilter conntrack helper. Bug: 195914327 Test: manual test as the follows 1. Connect to ftp.slackware.com with port 21 in active mode. 2. Check the PORT command success. Command: PORT 192,168,62,128,174,17 Response: 200 PORT command successful. 3. Download a file. Change-Id: I8e3b8d9323eb0e572f20c74442b55d4ee95abc2f --- .../networkstack/tethering/BpfCoordinator.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java index 5b39a23217..de76e89c79 100644 --- a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java +++ b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java @@ -131,6 +131,11 @@ public class BpfCoordinator { @VisibleForTesting static final int NF_CONNTRACK_UDP_TIMEOUT_STREAM = 180; + // List of TCP port numbers which aren't offloaded because the packets require the netfilter + // conntrack helper. See also TetherController::setForwardRules in netd. + static final short [] NON_OFFLOADED_UPSTREAM_IPV4_TCP_PORTS = new short [] { + 21 /* ftp */, 1723 /* pptp */}; + @VisibleForTesting enum StatsType { STATS_PER_IFACE, @@ -1556,7 +1561,18 @@ public class BpfCoordinator { 0 /* lastUsed, filled by bpf prog only */); } + private boolean requireOffload(ConntrackEvent e) { + if (e.tupleOrig.protoNum != OsConstants.IPPROTO_TCP) return true; + + for (final short port : NON_OFFLOADED_UPSTREAM_IPV4_TCP_PORTS) { + if (port == e.tupleOrig.dstPort) return false; + } + return true; + } + public void accept(ConntrackEvent e) { + if (!requireOffload(e)) return; + final ClientInfo tetherClient = getClientInfo(e.tupleOrig.srcIp); if (tetherClient == null) return;