Clean up BpfCoordinatorTest after refactors

Removed the use of a real IpServer instance in BpfCoordinatorTest,
as it is no longer needed after the refactors in aosp/2716773 and
aosp/3113123.

Test: atest TetheringTests
Bug: 294025403
Change-Id: I4760669372275a0165f4980705e328c80e0649a5
This commit is contained in:
KH Shi 2024-06-05 13:51:33 +00:00
commit 572b784fdc

View file

@ -25,8 +25,6 @@ import static android.net.NetworkStats.SET_DEFAULT;
import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL;
import static android.net.NetworkStats.UID_TETHERING;
import static android.net.TetheringManager.TETHERING_WIFI;
import static android.net.ip.IpServer.STATE_TETHERED;
import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED;
import static android.system.OsConstants.ETH_P_IP;
import static android.system.OsConstants.ETH_P_IPV6;
@ -79,9 +77,7 @@ import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.argThat;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
@ -100,11 +96,9 @@ import android.net.MacAddress;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkStats;
import android.net.RoutingCoordinatorManager;
import android.net.TetherOffloadRuleParcel;
import android.net.TetherStatsParcel;
import android.net.ip.IpServer;
import android.net.ip.RouterAdvertisementDaemon;
import android.os.Build;
import android.os.Handler;
import android.os.test.TestLooper;
@ -119,12 +113,10 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.dx.mockito.inline.extended.ExtendedMockito;
import com.android.internal.util.IndentingPrintWriter;
import com.android.modules.utils.build.SdkLevel;
import com.android.net.module.util.CollectionUtils;
import com.android.net.module.util.IBpfMap;
import com.android.net.module.util.InterfaceParams;
import com.android.net.module.util.NetworkStackConstants;
import com.android.net.module.util.SdkUtil.LateSdk;
import com.android.net.module.util.SharedLog;
import com.android.net.module.util.Struct.S32;
import com.android.net.module.util.bpf.Tether4Key;
@ -143,8 +135,6 @@ import com.android.networkstack.tethering.BpfCoordinator.BpfConntrackEventConsum
import com.android.networkstack.tethering.BpfCoordinator.ClientInfo;
import com.android.networkstack.tethering.BpfCoordinator.Ipv6DownstreamRule;
import com.android.networkstack.tethering.BpfCoordinator.Ipv6UpstreamRule;
import com.android.networkstack.tethering.metrics.TetheringMetrics;
import com.android.networkstack.tethering.util.InterfaceSet;
import com.android.testutils.DevSdkIgnoreRule;
import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter;
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
@ -209,11 +199,6 @@ public class BpfCoordinatorTest {
private static final MacAddress MAC_B = MacAddress.fromString("11:22:33:00:00:0b");
private static final MacAddress MAC_NULL = MacAddress.fromString("00:00:00:00:00:00");
private static final LinkAddress UPSTREAM_ADDRESS = new LinkAddress("2001:db8:0:1234::168/64");
private static final LinkAddress UPSTREAM_ADDRESS2 = new LinkAddress("2001:db8:0:abcd::168/64");
private static final Set<LinkAddress> UPSTREAM_ADDRESSES = Set.of(UPSTREAM_ADDRESS);
private static final Set<LinkAddress> UPSTREAM_ADDRESSES2 =
Set.of(UPSTREAM_ADDRESS, UPSTREAM_ADDRESS2);
private static final IpPrefix UPSTREAM_PREFIX = new IpPrefix("2001:db8:0:1234::/64");
private static final IpPrefix UPSTREAM_PREFIX2 = new IpPrefix("2001:db8:0:abcd::/64");
private static final Set<IpPrefix> UPSTREAM_PREFIXES = Set.of(UPSTREAM_PREFIX);
@ -449,13 +434,6 @@ public class BpfCoordinatorTest {
@Mock private TetheringConfiguration mTetherConfig;
@Mock private ConntrackMonitor mConntrackMonitor;
@Mock private IpNeighborMonitor mIpNeighborMonitor;
@Mock private RouterAdvertisementDaemon mRaDaemon;
@Mock private IpServer.Dependencies mIpServerDeps;
@Mock private IpServer.Callback mIpServerCallback;
@Mock private PrivateAddressCoordinator mAddressCoordinator;
private final LateSdk<RoutingCoordinatorManager> mRoutingCoordinatorManager =
new LateSdk<>(SdkLevel.isAtLeastS() ? mock(RoutingCoordinatorManager.class) : null);
@Mock private TetheringMetrics mTetheringMetrics;
// Late init since methods must be called by the thread that created this object.
private TestableNetworkStatsProviderCbBinder mTetherStatsProviderCb;
@ -575,24 +553,6 @@ public class BpfCoordinatorTest {
when(mTetherConfig.isBpfOffloadEnabled()).thenReturn(true /* default value */);
when(mIpServer.getInterfaceParams()).thenReturn(DOWNSTREAM_IFACE_PARAMS);
when(mIpServer2.getInterfaceParams()).thenReturn(DOWNSTREAM_IFACE_PARAMS2);
// Simulate the behavior of RoutingCoordinator
if (null != mRoutingCoordinatorManager.value) {
doAnswer(it -> {
final String fromIface = (String) it.getArguments()[0];
final String toIface = (String) it.getArguments()[1];
mNetd.tetherAddForward(fromIface, toIface);
mNetd.ipfwdAddInterfaceForward(fromIface, toIface);
return null;
}).when(mRoutingCoordinatorManager.value).addInterfaceForward(any(), any());
doAnswer(it -> {
final String fromIface = (String) it.getArguments()[0];
final String toIface = (String) it.getArguments()[1];
mNetd.ipfwdRemoveInterfaceForward(fromIface, toIface);
mNetd.tetherRemoveForward(fromIface, toIface);
return null;
}).when(mRoutingCoordinatorManager.value).removeInterfaceForward(any(), any());
}
}
private void waitForIdle() {
@ -605,48 +565,6 @@ public class BpfCoordinatorTest {
when(mNetd.tetherOffloadGetStats()).thenReturn(new TetherStatsParcel[0]);
}
@NonNull
private IpServer makeAndStartIpServer(String interfaceName, BpfCoordinator bpfCoordinator)
throws Exception {
final LinkAddress testAddress = new LinkAddress("192.168.42.5/24");
when(mIpServerDeps.getRouterAdvertisementDaemon(any())).thenReturn(mRaDaemon);
when(mIpServerDeps.getInterfaceParams(DOWNSTREAM_IFACE)).thenReturn(
DOWNSTREAM_IFACE_PARAMS);
when(mIpServerDeps.getInterfaceParams(UPSTREAM_IFACE)).thenReturn(UPSTREAM_IFACE_PARAMS);
when(mIpServerDeps.getInterfaceParams(UPSTREAM_IFACE2)).thenReturn(UPSTREAM_IFACE_PARAMS2);
when(mIpServerDeps.getInterfaceParams(IPSEC_IFACE)).thenReturn(IPSEC_IFACE_PARAMS);
when(mAddressCoordinator.requestDownstreamAddress(any(), anyInt(),
anyBoolean())).thenReturn(testAddress);
when(mRaDaemon.start()).thenReturn(true);
final IpServer ipServer = new IpServer(
interfaceName, mHandler, TETHERING_WIFI, new SharedLog("test"), mNetd,
bpfCoordinator, mRoutingCoordinatorManager, mIpServerCallback, mTetherConfig,
mAddressCoordinator, mTetheringMetrics, mIpServerDeps);
ipServer.start();
ipServer.sendMessage(IpServer.CMD_TETHER_REQUESTED, STATE_TETHERED);
mTestLooper.dispatchAll();
LinkProperties lp = new LinkProperties();
lp.setInterfaceName(UPSTREAM_IFACE);
lp.setLinkAddresses(UPSTREAM_ADDRESSES);
dispatchTetherConnectionChanged(ipServer, UPSTREAM_IFACE, lp, 0);
return ipServer;
}
private void dispatchTetherConnectionChanged(IpServer ipServer, String upstreamIface,
LinkProperties v6lp, int ttlAdjustment) {
dispatchTetherConnectionChanged(ipServer, upstreamIface);
ipServer.sendMessage(IpServer.CMD_IPV6_TETHER_UPDATE, ttlAdjustment, 0, v6lp);
mTestLooper.dispatchAll();
}
private void dispatchTetherConnectionChanged(IpServer ipServer, String upstreamIface) {
final InterfaceSet ifs = (upstreamIface != null) ? new InterfaceSet(upstreamIface) : null;
ipServer.sendMessage(IpServer.CMD_TETHER_CONNECTION_CHANGED, ifs);
mTestLooper.dispatchAll();
}
private void dispatchIpv6UpstreamChanged(BpfCoordinator bpfCoordinator, IpServer ipServer,
int upstreamIfindex, String upstreamIface, Set<IpPrefix> upstreamPrefixes) {
bpfCoordinator.maybeAddUpstreamToLookupTable(upstreamIfindex, upstreamIface);
@ -658,13 +576,11 @@ public class BpfCoordinatorTest {
private void recvNewNeigh(int ifindex, InetAddress addr, short nudState, MacAddress mac) {
mNeighborEventConsumer.accept(new NeighborEvent(0, RTM_NEWNEIGH, ifindex, addr,
nudState, mac));
mTestLooper.dispatchAll();
}
private void recvDelNeigh(int ifindex, InetAddress addr, short nudState, MacAddress mac) {
mNeighborEventConsumer.accept(new NeighborEvent(0, RTM_DELNEIGH, ifindex, addr,
nudState, mac));
mTestLooper.dispatchAll();
}
@NonNull
@ -2856,9 +2772,10 @@ public class BpfCoordinatorTest {
public void addRemoveIpv6ForwardingRules() throws Exception {
final int myIfindex = DOWNSTREAM_IFINDEX;
final int notMyIfindex = myIfindex - 1;
final BpfCoordinator coordinator = makeBpfCoordinator(false /* addDefaultIpServer */);
final IpServer ipServer = makeAndStartIpServer(DOWNSTREAM_IFACE, coordinator);
final BpfCoordinator coordinator = makeBpfCoordinator();
dispatchIpv6UpstreamChanged(
coordinator, mIpServer, UPSTREAM_IFINDEX, UPSTREAM_IFACE, UPSTREAM_PREFIXES);
resetNetdAndBpfMaps();
verifyNoMoreInteractions(mNetd, mBpfDownstream6Map, mBpfUpstream6Map);
@ -2907,10 +2824,8 @@ public class BpfCoordinatorTest {
resetNetdAndBpfMaps();
InOrder inOrder = inOrder(mNetd, mBpfDownstream6Map, mBpfUpstream6Map);
LinkProperties lp = new LinkProperties();
lp.setInterfaceName(UPSTREAM_IFACE2);
lp.setLinkAddresses(UPSTREAM_ADDRESSES);
dispatchTetherConnectionChanged(ipServer, UPSTREAM_IFACE2, lp, -1);
dispatchIpv6UpstreamChanged(
coordinator, mIpServer, UPSTREAM_IFINDEX2, UPSTREAM_IFACE2, UPSTREAM_PREFIXES);
final Ipv6DownstreamRule ruleA2 = buildTestDownstreamRule(
UPSTREAM_IFINDEX2, NEIGH_A, MAC_A);
final Ipv6DownstreamRule ruleB2 = buildTestDownstreamRule(
@ -2924,11 +2839,9 @@ public class BpfCoordinatorTest {
verifyNoUpstreamIpv6ForwardingChange(inOrder);
resetNetdAndBpfMaps();
// Upstream link addresses change result in updating the rules.
LinkProperties lp2 = new LinkProperties();
lp2.setInterfaceName(UPSTREAM_IFACE2);
lp2.setLinkAddresses(UPSTREAM_ADDRESSES2);
dispatchTetherConnectionChanged(ipServer, UPSTREAM_IFACE2, lp2, -1);
// Upstream prefixes change result in updating the rules.
dispatchIpv6UpstreamChanged(
coordinator, mIpServer, UPSTREAM_IFINDEX2, UPSTREAM_IFACE2, UPSTREAM_PREFIXES2);
verifyRemoveDownstreamRule(inOrder, ruleA2);
verifyRemoveDownstreamRule(inOrder, ruleB2);
verifyStopUpstreamIpv6Forwarding(inOrder, UPSTREAM_PREFIXES);
@ -2938,7 +2851,7 @@ public class BpfCoordinatorTest {
resetNetdAndBpfMaps();
// When the upstream is lost, rules are removed.
dispatchTetherConnectionChanged(ipServer, null, null, 0);
dispatchIpv6UpstreamChanged(coordinator, mIpServer, NO_UPSTREAM, null, NO_PREFIXES);
verifyStopUpstreamIpv6Forwarding(inOrder, UPSTREAM_PREFIXES2);
verifyRemoveDownstreamRule(ruleA2);
verifyRemoveDownstreamRule(ruleB2);
@ -2949,7 +2862,7 @@ public class BpfCoordinatorTest {
resetNetdAndBpfMaps();
// If the upstream is IPv4-only, no IPv6 rules are added to BPF map.
dispatchTetherConnectionChanged(ipServer, UPSTREAM_IFACE);
dispatchIpv6UpstreamChanged(coordinator, mIpServer, NO_UPSTREAM, null, NO_PREFIXES);
resetNetdAndBpfMaps();
recvNewNeigh(myIfindex, NEIGH_A, NUD_REACHABLE, MAC_A);
verifyNoUpstreamIpv6ForwardingChange(null);
@ -2959,8 +2872,8 @@ public class BpfCoordinatorTest {
// Rules can be added again once upstream IPv6 connectivity is available. The existing rules
// with an upstream of NO_UPSTREAM are reapplied.
lp.setInterfaceName(UPSTREAM_IFACE);
dispatchTetherConnectionChanged(ipServer, UPSTREAM_IFACE, lp, -1);
dispatchIpv6UpstreamChanged(
coordinator, mIpServer, UPSTREAM_IFINDEX, UPSTREAM_IFACE, UPSTREAM_PREFIXES);
verifyStartUpstreamIpv6Forwarding(null, UPSTREAM_IFINDEX, UPSTREAM_PREFIXES);
verifyAddDownstreamRule(ruleA);
recvNewNeigh(myIfindex, NEIGH_B, NUD_REACHABLE, MAC_B);
@ -2968,23 +2881,27 @@ public class BpfCoordinatorTest {
// If upstream IPv6 connectivity is lost, rules are removed.
resetNetdAndBpfMaps();
dispatchTetherConnectionChanged(ipServer, UPSTREAM_IFACE, null, 0);
dispatchIpv6UpstreamChanged(coordinator, mIpServer, NO_UPSTREAM, null, NO_PREFIXES);
verifyRemoveDownstreamRule(ruleA);
verifyRemoveDownstreamRule(ruleB);
verifyStopUpstreamIpv6Forwarding(null, UPSTREAM_PREFIXES);
// When upstream IPv6 connectivity comes back, upstream rules are added and downstream rules
// are reapplied.
lp.setInterfaceName(UPSTREAM_IFACE);
dispatchTetherConnectionChanged(ipServer, UPSTREAM_IFACE, lp, -1);
dispatchIpv6UpstreamChanged(
coordinator, mIpServer, UPSTREAM_IFINDEX, UPSTREAM_IFACE, UPSTREAM_PREFIXES);
verifyStartUpstreamIpv6Forwarding(null, UPSTREAM_IFINDEX, UPSTREAM_PREFIXES);
verifyAddDownstreamRule(ruleA);
verifyAddDownstreamRule(ruleB);
resetNetdAndBpfMaps();
// When the downstream interface goes down, rules are removed.
ipServer.stop();
mTestLooper.dispatchAll();
// Simulate receiving CMD_INTERFACE_DOWN in the BaseServingState of IpServer.
reset(mIpNeighborMonitor);
dispatchIpv6UpstreamChanged(coordinator, mIpServer, NO_UPSTREAM, null, NO_PREFIXES);
coordinator.tetherOffloadClientClear(mIpServer);
coordinator.removeIpServer(mIpServer);
verifyStopUpstreamIpv6Forwarding(null, UPSTREAM_PREFIXES);
verifyRemoveDownstreamRule(ruleA);
verifyRemoveDownstreamRule(ruleB);
@ -3005,8 +2922,9 @@ public class BpfCoordinatorTest {
// [1] Enable BPF offload.
// A neighbor that is added or deleted causes the rule to be added or removed.
final BpfCoordinator coordinator = makeBpfCoordinator(false /* addDefaultIpServer */);
final IpServer ipServer = makeAndStartIpServer(DOWNSTREAM_IFACE, coordinator);
final BpfCoordinator coordinator = makeBpfCoordinator();
dispatchIpv6UpstreamChanged(
coordinator, mIpServer, UPSTREAM_IFINDEX, UPSTREAM_IFACE, UPSTREAM_PREFIXES);
resetNetdAndBpfMaps();
recvNewNeigh(myIfindex, NEIGH_A, NUD_REACHABLE, MAC_A);
@ -3021,18 +2939,15 @@ public class BpfCoordinatorTest {
resetNetdAndBpfMaps();
// Upstream IPv6 connectivity change causes upstream rules change.
LinkProperties lp2 = new LinkProperties();
lp2.setInterfaceName(UPSTREAM_IFACE2);
lp2.setLinkAddresses(UPSTREAM_ADDRESSES2);
dispatchTetherConnectionChanged(ipServer, UPSTREAM_IFACE2, lp2, 0);
dispatchIpv6UpstreamChanged(
coordinator, mIpServer, UPSTREAM_IFINDEX2, UPSTREAM_IFACE2, UPSTREAM_PREFIXES2);
verifyStartUpstreamIpv6Forwarding(null, UPSTREAM_IFINDEX2, UPSTREAM_PREFIXES2);
resetNetdAndBpfMaps();
// [2] Disable BPF offload.
// A neighbor that is added or deleted doesn’t cause the rule to be added or removed.
when(mTetherConfig.isBpfOffloadEnabled()).thenReturn(false);
final BpfCoordinator coordinator2 = makeBpfCoordinator(false /* addDefaultIpServer */);
final IpServer ipServer2 = makeAndStartIpServer(DOWNSTREAM_IFACE, coordinator2);
final BpfCoordinator coordinator2 = makeBpfCoordinator();
verifyNoUpstreamIpv6ForwardingChange(null);
resetNetdAndBpfMaps();
@ -3045,7 +2960,8 @@ public class BpfCoordinatorTest {
resetNetdAndBpfMaps();
// Upstream IPv6 connectivity change doesn't cause the rule to be added or removed.
dispatchTetherConnectionChanged(ipServer2, UPSTREAM_IFACE2, lp2, 0);
dispatchIpv6UpstreamChanged(
coordinator, mIpServer2, UPSTREAM_IFINDEX2, UPSTREAM_IFACE2, NO_PREFIXES);
verifyNoUpstreamIpv6ForwardingChange(null);
verifyNeverRemoveDownstreamRule();
resetNetdAndBpfMaps();
@ -3054,8 +2970,7 @@ public class BpfCoordinatorTest {
@Test
public void doesNotStartIpNeighborMonitorIfBpfOffloadDisabled() throws Exception {
when(mTetherConfig.isBpfOffloadEnabled()).thenReturn(false);
final BpfCoordinator coordinator = makeBpfCoordinator(false /* addDefaultIpServer */);
final IpServer ipServer = makeAndStartIpServer(DOWNSTREAM_IFACE, coordinator);
final BpfCoordinator coordinator = makeBpfCoordinator();
// IP neighbor monitor doesn't start if BPF offload is disabled.
verify(mIpNeighborMonitor, never()).start();
@ -3063,16 +2978,11 @@ public class BpfCoordinatorTest {
@Test
public void testSkipVirtualNetworkInBpf() throws Exception {
final BpfCoordinator coordinator = makeBpfCoordinator(false /* addDefaultIpServer */);
final IpServer ipServer = makeAndStartIpServer(DOWNSTREAM_IFACE, coordinator);
final LinkProperties v6Only = new LinkProperties();
v6Only.setInterfaceName(IPSEC_IFACE);
v6Only.setLinkAddresses(UPSTREAM_ADDRESSES);
final BpfCoordinator coordinator = makeBpfCoordinator();
resetNetdAndBpfMaps();
dispatchTetherConnectionChanged(ipServer, IPSEC_IFACE, v6Only, 0);
verify(mNetd).tetherAddForward(DOWNSTREAM_IFACE, IPSEC_IFACE);
verify(mNetd).ipfwdAddInterfaceForward(DOWNSTREAM_IFACE, IPSEC_IFACE);
dispatchIpv6UpstreamChanged(
coordinator, mIpServer, IPSEC_IFINDEX, IPSEC_IFACE, UPSTREAM_PREFIXES);
verifyNeverAddUpstreamRule();
recvNewNeigh(DOWNSTREAM_IFINDEX, NEIGH_A, NUD_REACHABLE, MAC_A);
@ -3081,8 +2991,7 @@ public class BpfCoordinatorTest {
@Test
public void addRemoveTetherClient() throws Exception {
final BpfCoordinator coordinator = makeBpfCoordinator(false /* addDefaultIpServer */);
final IpServer ipServer = makeAndStartIpServer(DOWNSTREAM_IFACE, coordinator);
final BpfCoordinator coordinator = makeBpfCoordinator();
final int myIfindex = DOWNSTREAM_IFINDEX;
final int notMyIfindex = myIfindex - 1;
@ -3091,33 +3000,36 @@ public class BpfCoordinatorTest {
final InetAddress neighLL = InetAddresses.parseNumericAddress("169.254.0.1");
final InetAddress neighMC = InetAddresses.parseNumericAddress("224.0.0.1");
dispatchIpv6UpstreamChanged(
coordinator, mIpServer, UPSTREAM_IFINDEX, UPSTREAM_IFACE, UPSTREAM_PREFIXES);
// Events on other interfaces are ignored.
recvNewNeigh(notMyIfindex, neighA, NUD_REACHABLE, MAC_A);
assertNull(mTetherClients.get(ipServer));
assertNull(mTetherClients.get(mIpServer));
// Events on this interface are received and sent to BpfCoordinator.
recvNewNeigh(myIfindex, neighA, NUD_REACHABLE, MAC_A);
assertClientInfoExists(ipServer,
assertClientInfoExists(mIpServer,
new ClientInfo(myIfindex, DOWNSTREAM_MAC, (Inet4Address) neighA, MAC_A));
recvNewNeigh(myIfindex, neighB, NUD_REACHABLE, MAC_B);
assertClientInfoExists(ipServer,
assertClientInfoExists(mIpServer,
new ClientInfo(myIfindex, DOWNSTREAM_MAC, (Inet4Address) neighB, MAC_B));
// Link-local and multicast neighbors are ignored.
recvNewNeigh(myIfindex, neighLL, NUD_REACHABLE, MAC_A);
assertClientInfoDoesNotExist(ipServer, (Inet4Address) neighLL);
assertClientInfoDoesNotExist(mIpServer, (Inet4Address) neighLL);
recvNewNeigh(myIfindex, neighMC, NUD_REACHABLE, MAC_A);
assertClientInfoDoesNotExist(ipServer, (Inet4Address) neighMC);
assertClientInfoDoesNotExist(mIpServer, (Inet4Address) neighMC);
// A neighbor that is no longer valid causes the client to be removed.
// NUD_FAILED events do not have a MAC address.
recvNewNeigh(myIfindex, neighA, NUD_FAILED, null);
assertClientInfoDoesNotExist(ipServer, (Inet4Address) neighA);
assertClientInfoDoesNotExist(mIpServer, (Inet4Address) neighA);
// A neighbor that is deleted causes the client to be removed.
recvDelNeigh(myIfindex, neighB, NUD_STALE, MAC_B);
// When last client information is deleted, IpServer will be removed from mTetherClients
assertNull(mTetherClients.get(ipServer));
assertNull(mTetherClients.get(mIpServer));
}
}