rename InterfaceMapUpdater to InterfaceMapHelper
since it doesn't actually update any more... Done via: git grep InterfaceMapUpdater | cut -d: -f1 | sort -u | while read i; do sed -i -r 's@InterfaceMapUpdater@InterfaceMapHelper@g' "$i"; done git mv ./tests/unit/java/com/android/server/net/BpfInterfaceMapUpdaterTest.java ./tests/unit/java/com/android/server/net/BpfInterfaceMapHelperTest.java git mv ./service-t/src/com/android/server/net/BpfInterfaceMapUpdater.java ./service-t/src/com/android/server/net/BpfInterfaceMapHelper.java Test: TreeHugger atest libnetworkstats_test atest FrameworksNetTests:android.net.connectivity.com.android.server.net.BpfInterfaceMapHelperTest atest NetworkStackIntegrationTests:android.net.NetworkStatsIntegrationTest atest --iterations=100 NetworkStackIntegrationTests:android.net.NetworkStatsIntegrationTest Signed-off-by: Maciej Żenczykowski <maze@google.com> Change-Id: I07b57158347757f3f8dc4f24803a9bbf30445f7d
This commit is contained in:
parent
8035dbc881
commit
9c82d9e693
4 changed files with 24 additions and 24 deletions
109
service-t/src/com/android/server/net/BpfInterfaceMapHelper.java
Normal file
109
service-t/src/com/android/server/net/BpfInterfaceMapHelper.java
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.server.net;
|
||||
|
||||
import android.os.Build;
|
||||
import android.content.Context;
|
||||
import android.net.INetd;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceSpecificException;
|
||||
import android.system.ErrnoException;
|
||||
import android.util.IndentingPrintWriter;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.net.module.util.BaseNetdUnsolicitedEventListener;
|
||||
import com.android.net.module.util.BpfDump;
|
||||
import com.android.net.module.util.BpfMap;
|
||||
import com.android.net.module.util.IBpfMap;
|
||||
import com.android.net.module.util.InterfaceParams;
|
||||
import com.android.net.module.util.Struct.S32;
|
||||
|
||||
/**
|
||||
* Monitor interface added (without removed) and right interface name and its index to bpf map.
|
||||
*/
|
||||
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
|
||||
public class BpfInterfaceMapHelper {
|
||||
private static final String TAG = BpfInterfaceMapHelper.class.getSimpleName();
|
||||
// This is current path but may be changed soon.
|
||||
private static final String IFACE_INDEX_NAME_MAP_PATH =
|
||||
"/sys/fs/bpf/netd_shared/map_netd_iface_index_name_map";
|
||||
private final IBpfMap<S32, InterfaceMapValue> mIndexToIfaceBpfMap;
|
||||
|
||||
public BpfInterfaceMapHelper() {
|
||||
this(new Dependencies());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public BpfInterfaceMapHelper(Dependencies deps) {
|
||||
mIndexToIfaceBpfMap = deps.getInterfaceMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Dependencies of BpfInerfaceMapUpdater, for injection in tests.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public static class Dependencies {
|
||||
/** Create BpfMap for updating interface and index mapping. */
|
||||
public IBpfMap<S32, InterfaceMapValue> getInterfaceMap() {
|
||||
try {
|
||||
return new BpfMap<>(IFACE_INDEX_NAME_MAP_PATH,
|
||||
S32.class, InterfaceMapValue.class);
|
||||
} catch (ErrnoException e) {
|
||||
Log.e(TAG, "Cannot create interface map: " + e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** get interface name by interface index from bpf map */
|
||||
public String getIfNameByIndex(final int index) {
|
||||
try {
|
||||
final InterfaceMapValue value = mIndexToIfaceBpfMap.getValue(new S32(index));
|
||||
if (value == null) {
|
||||
Log.e(TAG, "No if name entry for index " + index);
|
||||
return null;
|
||||
}
|
||||
return value.getInterfaceNameString();
|
||||
} catch (ErrnoException e) {
|
||||
Log.e(TAG, "Failed to get entry for index " + index + ": " + e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump BPF map
|
||||
*
|
||||
* @param pw print writer
|
||||
*/
|
||||
public void dump(final IndentingPrintWriter pw) {
|
||||
pw.println("BPF map status:");
|
||||
pw.increaseIndent();
|
||||
BpfDump.dumpMapStatus(mIndexToIfaceBpfMap, pw, "IfaceIndexNameMap",
|
||||
IFACE_INDEX_NAME_MAP_PATH);
|
||||
pw.decreaseIndent();
|
||||
pw.println("BPF map content:");
|
||||
pw.increaseIndent();
|
||||
BpfDump.dumpMap(mIndexToIfaceBpfMap, pw, "IfaceIndexNameMap",
|
||||
(key, value) -> "ifaceIndex=" + key.val
|
||||
+ " ifaceName=" + value.getInterfaceNameString());
|
||||
pw.decreaseIndent();
|
||||
}
|
||||
}
|
||||
|
|
@ -476,7 +476,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||
private final LocationPermissionChecker mLocationPermissionChecker;
|
||||
|
||||
@NonNull
|
||||
private final BpfInterfaceMapUpdater mInterfaceMapUpdater;
|
||||
private final BpfInterfaceMapHelper mInterfaceMapHelper;
|
||||
|
||||
@Nullable
|
||||
private final SkDestroyListener mSkDestroyListener;
|
||||
|
|
@ -628,7 +628,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||
mContentObserver = mDeps.makeContentObserver(mHandler, mSettings,
|
||||
mNetworkStatsSubscriptionsMonitor);
|
||||
mLocationPermissionChecker = mDeps.makeLocationPermissionChecker(mContext);
|
||||
mInterfaceMapUpdater = mDeps.makeBpfInterfaceMapUpdater();
|
||||
mInterfaceMapHelper = mDeps.makeBpfInterfaceMapHelper();
|
||||
mUidCounterSetMap = mDeps.getUidCounterSetMap();
|
||||
mCookieTagMap = mDeps.getCookieTagMap();
|
||||
mStatsMapA = mDeps.getStatsMapA();
|
||||
|
|
@ -797,10 +797,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||
return new LocationPermissionChecker(context);
|
||||
}
|
||||
|
||||
/** Create BpfInterfaceMapUpdater to update bpf interface map. */
|
||||
/** Create BpfInterfaceMapHelper to update bpf interface map. */
|
||||
@NonNull
|
||||
public BpfInterfaceMapUpdater makeBpfInterfaceMapUpdater() {
|
||||
return new BpfInterfaceMapUpdater();
|
||||
public BpfInterfaceMapHelper makeBpfInterfaceMapHelper() {
|
||||
return new BpfInterfaceMapHelper();
|
||||
}
|
||||
|
||||
/** Get counter sets map for each UID. */
|
||||
|
|
@ -2887,9 +2887,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||
}
|
||||
|
||||
pw.println();
|
||||
pw.println("InterfaceMapUpdater:");
|
||||
pw.println("InterfaceMapHelper:");
|
||||
pw.increaseIndent();
|
||||
mInterfaceMapUpdater.dump(pw);
|
||||
mInterfaceMapHelper.dump(pw);
|
||||
pw.decreaseIndent();
|
||||
|
||||
pw.println();
|
||||
|
|
@ -3036,7 +3036,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||
BpfDump.dumpMap(statsMap, pw, mapName,
|
||||
"ifaceIndex ifaceName tag_hex uid_int cnt_set rxBytes rxPackets txBytes txPackets",
|
||||
(key, value) -> {
|
||||
final String ifName = mInterfaceMapUpdater.getIfNameByIndex(key.ifaceIndex);
|
||||
final String ifName = mInterfaceMapHelper.getIfNameByIndex(key.ifaceIndex);
|
||||
return key.ifaceIndex + " "
|
||||
+ (ifName != null ? ifName : "unknown") + " "
|
||||
+ "0x" + Long.toHexString(key.tag) + " "
|
||||
|
|
@ -3054,7 +3054,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||
BpfDump.dumpMap(mIfaceStatsMap, pw, "mIfaceStatsMap",
|
||||
"ifaceIndex ifaceName rxBytes rxPackets txBytes txPackets",
|
||||
(key, value) -> {
|
||||
final String ifName = mInterfaceMapUpdater.getIfNameByIndex(key.val);
|
||||
final String ifName = mInterfaceMapHelper.getIfNameByIndex(key.val);
|
||||
return key.val + " "
|
||||
+ (ifName != null ? ifName : "unknown") + " "
|
||||
+ value.rxBytes + " "
|
||||
|
|
|
|||
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.net;
|
||||
|
||||
import static android.system.OsConstants.EPERM;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.INetd;
|
||||
import android.net.MacAddress;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.test.TestLooper;
|
||||
import android.system.ErrnoException;
|
||||
import android.util.IndentingPrintWriter;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.net.module.util.BaseNetdUnsolicitedEventListener;
|
||||
import com.android.net.module.util.IBpfMap;
|
||||
import com.android.net.module.util.InterfaceParams;
|
||||
import com.android.net.module.util.Struct.S32;
|
||||
import com.android.testutils.DevSdkIgnoreRule;
|
||||
import com.android.testutils.DevSdkIgnoreRunner;
|
||||
import com.android.testutils.TestBpfMap;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(DevSdkIgnoreRunner.class)
|
||||
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.S_V2)
|
||||
public final class BpfInterfaceMapHelperTest {
|
||||
private static final int TEST_INDEX = 1;
|
||||
private static final int TEST_INDEX2 = 2;
|
||||
private static final String TEST_INTERFACE_NAME = "test1";
|
||||
private static final String TEST_INTERFACE_NAME2 = "test2";
|
||||
|
||||
private BaseNetdUnsolicitedEventListener mListener;
|
||||
private BpfInterfaceMapHelper mUpdater;
|
||||
private IBpfMap<S32, InterfaceMapValue> mBpfMap =
|
||||
spy(new TestBpfMap<>(S32.class, InterfaceMapValue.class));
|
||||
|
||||
private class TestDependencies extends BpfInterfaceMapHelper.Dependencies {
|
||||
@Override
|
||||
public IBpfMap<S32, InterfaceMapValue> getInterfaceMap() {
|
||||
return mBpfMap;
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mUpdater = new BpfInterfaceMapHelper(new TestDependencies());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetIfNameByIndex() throws Exception {
|
||||
mBpfMap.updateEntry(new S32(TEST_INDEX), new InterfaceMapValue(TEST_INTERFACE_NAME));
|
||||
assertEquals(TEST_INTERFACE_NAME, mUpdater.getIfNameByIndex(TEST_INDEX));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetIfNameByIndexNoEntry() {
|
||||
assertNull(mUpdater.getIfNameByIndex(TEST_INDEX));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetIfNameByIndexException() throws Exception {
|
||||
doThrow(new ErrnoException("", EPERM)).when(mBpfMap).getValue(new S32(TEST_INDEX));
|
||||
assertNull(mUpdater.getIfNameByIndex(TEST_INDEX));
|
||||
}
|
||||
|
||||
private void assertDumpContains(final String dump, final String message) {
|
||||
assertTrue(String.format("dump(%s) does not contain '%s'", dump, message),
|
||||
dump.contains(message));
|
||||
}
|
||||
|
||||
private String getDump() {
|
||||
final StringWriter sw = new StringWriter();
|
||||
mUpdater.dump(new IndentingPrintWriter(new PrintWriter(sw), " "));
|
||||
return sw.toString();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDump() throws ErrnoException {
|
||||
mBpfMap.updateEntry(new S32(TEST_INDEX), new InterfaceMapValue(TEST_INTERFACE_NAME));
|
||||
mBpfMap.updateEntry(new S32(TEST_INDEX2), new InterfaceMapValue(TEST_INTERFACE_NAME2));
|
||||
|
||||
final String dump = getDump();
|
||||
assertDumpContains(dump, "IfaceIndexNameMap: OK");
|
||||
assertDumpContains(dump, "ifaceIndex=1 ifaceName=test1");
|
||||
assertDumpContains(dump, "ifaceIndex=2 ifaceName=test2");
|
||||
}
|
||||
}
|
||||
|
|
@ -254,7 +254,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
|
|||
private @Mock AlarmManager mAlarmManager;
|
||||
@Mock
|
||||
private NetworkStatsSubscriptionsMonitor mNetworkStatsSubscriptionsMonitor;
|
||||
private @Mock BpfInterfaceMapUpdater mBpfInterfaceMapUpdater;
|
||||
private @Mock BpfInterfaceMapHelper mBpfInterfaceMapHelper;
|
||||
private HandlerThread mHandlerThread;
|
||||
@Mock
|
||||
private LocationPermissionChecker mLocationPermissionChecker;
|
||||
|
|
@ -519,8 +519,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
|
|||
}
|
||||
|
||||
@Override
|
||||
public BpfInterfaceMapUpdater makeBpfInterfaceMapUpdater() {
|
||||
return mBpfInterfaceMapUpdater;
|
||||
public BpfInterfaceMapHelper makeBpfInterfaceMapHelper() {
|
||||
return mBpfInterfaceMapHelper;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -2763,13 +2763,13 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
|
|||
|
||||
@Test
|
||||
public void testDumpStatsMap() throws ErrnoException {
|
||||
doReturn("wlan0").when(mBpfInterfaceMapUpdater).getIfNameByIndex(10 /* index */);
|
||||
doReturn("wlan0").when(mBpfInterfaceMapHelper).getIfNameByIndex(10 /* index */);
|
||||
doTestDumpStatsMap("wlan0");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDumpStatsMapUnknownInterface() throws ErrnoException {
|
||||
doReturn(null).when(mBpfInterfaceMapUpdater).getIfNameByIndex(10 /* index */);
|
||||
doReturn(null).when(mBpfInterfaceMapHelper).getIfNameByIndex(10 /* index */);
|
||||
doTestDumpStatsMap("unknown");
|
||||
}
|
||||
|
||||
|
|
@ -2784,13 +2784,13 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
|
|||
|
||||
@Test
|
||||
public void testDumpIfaceStatsMap() throws Exception {
|
||||
doReturn("wlan0").when(mBpfInterfaceMapUpdater).getIfNameByIndex(10 /* index */);
|
||||
doReturn("wlan0").when(mBpfInterfaceMapHelper).getIfNameByIndex(10 /* index */);
|
||||
doTestDumpIfaceStatsMap("wlan0");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDumpIfaceStatsMapUnknownInterface() throws Exception {
|
||||
doReturn(null).when(mBpfInterfaceMapUpdater).getIfNameByIndex(10 /* index */);
|
||||
doReturn(null).when(mBpfInterfaceMapHelper).getIfNameByIndex(10 /* index */);
|
||||
doTestDumpIfaceStatsMap("unknown");
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue