Merge "Skip bpf offload if upstream interface is VCN" am: 097d65b0f3
Original change: https://android-review.googlesource.com/c/platform/packages/modules/Connectivity/+/1764307 Change-Id: Iee7c4eeaad1aa00b47699bec2838e692ae88edcf
This commit is contained in:
@@ -26,6 +26,7 @@ import static android.net.util.TetheringMessageBase.BASE_IPSERVER;
|
||||
import static android.system.OsConstants.RT_SCOPE_UNIVERSE;
|
||||
|
||||
import static com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTH;
|
||||
import static com.android.networkstack.tethering.UpstreamNetworkState.isVcnInterface;
|
||||
|
||||
import android.net.INetd;
|
||||
import android.net.INetworkStackStatusCallback;
|
||||
@@ -755,6 +756,9 @@ public class IpServer extends StateMachine {
|
||||
// deprecation of any existing RA data.
|
||||
|
||||
setRaParams(params);
|
||||
// Be aware that updateIpv6ForwardingRules use mLastIPv6LinkProperties, so this line should
|
||||
// be eariler than updateIpv6ForwardingRules.
|
||||
// TODO: avoid this dependencies and move this logic into BpfCoordinator.
|
||||
mLastIPv6LinkProperties = v6only;
|
||||
|
||||
updateIpv6ForwardingRules(mLastIPv6UpstreamIfindex, upstreamIfIndex, null);
|
||||
@@ -892,12 +896,20 @@ public class IpServer extends StateMachine {
|
||||
mBpfCoordinator.tetherOffloadRuleUpdate(this, newIfindex);
|
||||
}
|
||||
|
||||
private boolean isIpv6VcnNetworkInterface() {
|
||||
if (mLastIPv6LinkProperties == null) return false;
|
||||
|
||||
return isVcnInterface(mLastIPv6LinkProperties.getInterfaceName());
|
||||
}
|
||||
|
||||
// Handles all updates to IPv6 forwarding rules. These can currently change only if the upstream
|
||||
// changes or if a neighbor event is received.
|
||||
private void updateIpv6ForwardingRules(int prevUpstreamIfindex, int upstreamIfindex,
|
||||
NeighborEvent e) {
|
||||
// If we no longer have an upstream, clear forwarding rules and do nothing else.
|
||||
if (upstreamIfindex == 0) {
|
||||
// If no longer have an upstream or it is virtual network, clear forwarding rules and do
|
||||
// nothing else.
|
||||
// TODO: Rather than always clear rules, ensure whether ipv6 ever enable first.
|
||||
if (upstreamIfindex == 0 || isIpv6VcnNetworkInterface()) {
|
||||
clearIpv6ForwardingRules();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import static android.system.OsConstants.ETH_P_IPV6;
|
||||
import static com.android.networkstack.tethering.BpfUtils.DOWNSTREAM;
|
||||
import static com.android.networkstack.tethering.BpfUtils.UPSTREAM;
|
||||
import static com.android.networkstack.tethering.TetheringConfiguration.DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS;
|
||||
import static com.android.networkstack.tethering.UpstreamNetworkState.isVcnInterface;
|
||||
|
||||
import android.app.usage.NetworkStatsManager;
|
||||
import android.net.INetd;
|
||||
@@ -677,6 +678,8 @@ public class BpfCoordinator {
|
||||
|
||||
if (upstreamIfindex == 0 || TextUtils.isEmpty(upstreamIface)) return;
|
||||
|
||||
if (isVcnInterface(upstreamIface)) return;
|
||||
|
||||
// The same interface index to name mapping may be added by different IpServer objects or
|
||||
// re-added by reconnection on the same upstream interface. Ignore the duplicate one.
|
||||
final String iface = mInterfaceNames.get(upstreamIfindex);
|
||||
@@ -844,9 +847,10 @@ public class BpfCoordinator {
|
||||
// TODO: need to consider 464xlat.
|
||||
if (ns != null && ns.linkProperties != null && ns.linkProperties.hasIpv4Address()) {
|
||||
// TODO: support ether ip upstream interface.
|
||||
final InterfaceParams params = mDeps.getInterfaceParams(
|
||||
ns.linkProperties.getInterfaceName());
|
||||
if (params != null && !params.hasMacAddress /* raw ip upstream only */) {
|
||||
final String ifaceName = ns.linkProperties.getInterfaceName();
|
||||
final InterfaceParams params = mDeps.getInterfaceParams(ifaceName);
|
||||
final boolean isVcn = isVcnInterface(ifaceName);
|
||||
if (!isVcn && params != null && !params.hasMacAddress /* raw ip upstream only */) {
|
||||
upstreamIndex = params.index;
|
||||
}
|
||||
}
|
||||
@@ -890,6 +894,8 @@ public class BpfCoordinator {
|
||||
* TODO: consider error handling if the attach program failed.
|
||||
*/
|
||||
public void maybeAttachProgram(@NonNull String intIface, @NonNull String extIface) {
|
||||
if (isVcnInterface(extIface)) return;
|
||||
|
||||
if (forwardingPairExists(intIface, extIface)) return;
|
||||
|
||||
boolean firstDownstreamForThisUpstream = !isAnyForwardingPairOnUpstream(extIface);
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.android.networkstack.tethering;
|
||||
|
||||
import static android.net.INetd.IPSEC_INTERFACE_PREFIX;
|
||||
|
||||
import android.net.LinkProperties;
|
||||
import android.net.Network;
|
||||
import android.net.NetworkCapabilities;
|
||||
@@ -48,4 +50,9 @@ public class UpstreamNetworkState {
|
||||
networkCapabilities == null ? "null" : networkCapabilities,
|
||||
linkProperties == null ? "null" : linkProperties);
|
||||
}
|
||||
|
||||
/** Check whether the interface is VCN. */
|
||||
public static boolean isVcnInterface(@NonNull String iface) {
|
||||
return iface.startsWith(IPSEC_INTERFACE_PREFIX);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,8 +146,10 @@ public class IpServerTest {
|
||||
private static final String IFACE_NAME = "testnet1";
|
||||
private static final String UPSTREAM_IFACE = "upstream0";
|
||||
private static final String UPSTREAM_IFACE2 = "upstream1";
|
||||
private static final String IPSEC_IFACE = "ipsec0";
|
||||
private static final int UPSTREAM_IFINDEX = 101;
|
||||
private static final int UPSTREAM_IFINDEX2 = 102;
|
||||
private static final int IPSEC_IFINDEX = 103;
|
||||
private static final String BLUETOOTH_IFACE_ADDR = "192.168.44.1";
|
||||
private static final int BLUETOOTH_DHCP_PREFIX_LENGTH = 24;
|
||||
private static final int DHCP_LEASE_TIME_SECS = 3600;
|
||||
@@ -160,6 +162,8 @@ public class IpServerTest {
|
||||
private static final InterfaceParams UPSTREAM_IFACE_PARAMS2 = new InterfaceParams(
|
||||
UPSTREAM_IFACE2, UPSTREAM_IFINDEX2, MacAddress.ALL_ZEROS_ADDRESS,
|
||||
1500 /* defaultMtu */);
|
||||
private static final InterfaceParams IPSEC_IFACE_PARAMS = new InterfaceParams(
|
||||
IPSEC_IFACE, IPSEC_IFINDEX, MacAddress.ALL_ZEROS_ADDRESS, 1500 /* defaultMtu */);
|
||||
|
||||
private static final int MAKE_DHCPSERVER_TIMEOUT_MS = 1000;
|
||||
|
||||
@@ -208,6 +212,7 @@ public class IpServerTest {
|
||||
when(mDependencies.getInterfaceParams(IFACE_NAME)).thenReturn(TEST_IFACE_PARAMS);
|
||||
when(mDependencies.getInterfaceParams(UPSTREAM_IFACE)).thenReturn(UPSTREAM_IFACE_PARAMS);
|
||||
when(mDependencies.getInterfaceParams(UPSTREAM_IFACE2)).thenReturn(UPSTREAM_IFACE_PARAMS2);
|
||||
when(mDependencies.getInterfaceParams(IPSEC_IFACE)).thenReturn(IPSEC_IFACE_PARAMS);
|
||||
|
||||
mInterfaceConfiguration = new InterfaceConfigurationParcel();
|
||||
mInterfaceConfiguration.flags = new String[0];
|
||||
@@ -1453,4 +1458,23 @@ public class IpServerTest {
|
||||
public void testDadProxyUpdates_EnabledAfterR() throws Exception {
|
||||
checkDadProxyEnabled(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkipVirtualNetworkInBpf() throws Exception {
|
||||
initTetheredStateMachine(TETHERING_BLUETOOTH, null);
|
||||
final LinkProperties v6Only = new LinkProperties();
|
||||
v6Only.setInterfaceName(IPSEC_IFACE);
|
||||
dispatchTetherConnectionChanged(IPSEC_IFACE, v6Only, 0);
|
||||
|
||||
verify(mBpfCoordinator).maybeAttachProgram(IFACE_NAME, IPSEC_IFACE);
|
||||
verify(mNetd).tetherAddForward(IFACE_NAME, IPSEC_IFACE);
|
||||
verify(mNetd).ipfwdAddInterfaceForward(IFACE_NAME, IPSEC_IFACE);
|
||||
|
||||
final int myIfindex = TEST_IFACE_PARAMS.index;
|
||||
final InetAddress neigh = InetAddresses.parseNumericAddress("2001:db8::1");
|
||||
final MacAddress mac = MacAddress.fromString("00:00:00:00:00:0a");
|
||||
recvNewNeigh(myIfindex, neigh, NUD_REACHABLE, mac);
|
||||
verify(mBpfCoordinator, never()).tetherOffloadRuleAdd(
|
||||
mIpServer, makeForwardingRule(IPSEC_IFINDEX, neigh, mac));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1129,6 +1129,7 @@ public class BpfCoordinatorTest {
|
||||
final String intIface1 = "wlan1";
|
||||
final String intIface2 = "rndis0";
|
||||
final String extIface = "rmnet_data0";
|
||||
final String virtualIface = "ipsec0";
|
||||
final BpfUtils mockMarkerBpfUtils = staticMockMarker(BpfUtils.class);
|
||||
final BpfCoordinator coordinator = makeBpfCoordinator();
|
||||
|
||||
@@ -1164,6 +1165,14 @@ public class BpfCoordinatorTest {
|
||||
ExtendedMockito.verify(() -> BpfUtils.detachProgram(intIface1));
|
||||
ExtendedMockito.verifyNoMoreInteractions(mockMarkerBpfUtils);
|
||||
ExtendedMockito.clearInvocations(mockMarkerBpfUtils);
|
||||
|
||||
// [6] Skip attaching if upstream is virtual interface.
|
||||
coordinator.maybeAttachProgram(intIface1, virtualIface);
|
||||
ExtendedMockito.verify(() -> BpfUtils.attachProgram(extIface, DOWNSTREAM), never());
|
||||
ExtendedMockito.verify(() -> BpfUtils.attachProgram(intIface1, UPSTREAM), never());
|
||||
ExtendedMockito.verifyNoMoreInteractions(mockMarkerBpfUtils);
|
||||
ExtendedMockito.clearInvocations(mockMarkerBpfUtils);
|
||||
|
||||
} finally {
|
||||
mockSession.finishMocking();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user