Move uidOwnerMap dump to BpfNetMaps

Before this CL
....
mUidOwnerMap:
10050  IIF_MATCH LOCKDOWN_VPN_MATCH 0
10061  HAPPY_BOX_MATCH
10091  HAPPY_BOX_MATCH IIF_MATCH LOCKDOWN_VPN_MATCH 0
....

After this CL
....
sUidOwnerMap:
  10050 IIF_MATCH LOCKDOWN_VPN_MATCH 0
  10061 HAPPY_BOX_MATCH
  10091 HAPPY_BOX_MATCH IIF_MATCH LOCKDOWN_VPN_MATCH 0
....

Bug: 217624062
Test: dumpsys connectivity trafficcontroller, atest BpfNetMapsTest
Change-Id: I0e2358e462824273a89fcba6e19e75a233f9fe18
This commit is contained in:
Motomu Utsumi
2022-09-02 17:01:25 +09:00
parent 310850f210
commit 956d86ccdf
4 changed files with 98 additions and 67 deletions

View File

@@ -697,26 +697,6 @@ void TrafficController::dump(int fd, bool verbose) {
dw.println("mConfigurationMap read stats map configure failed with error: %s", dw.println("mConfigurationMap read stats map configure failed with error: %s",
configuration.error().message().c_str()); configuration.error().message().c_str());
} }
dumpBpfMap("mUidOwnerMap", dw, "");
const auto printUidMatchInfo = [&dw, this](const uint32_t& key, const UidOwnerValue& value,
const BpfMap<uint32_t, UidOwnerValue>&) {
if (value.rule & IIF_MATCH) {
auto ifname = mIfaceIndexNameMap.readValue(value.iif);
if (ifname.ok()) {
dw.println("%u %s %s", key, uidMatchTypeToString(value.rule).c_str(),
ifname.value().name);
} else {
dw.println("%u %s %u", key, uidMatchTypeToString(value.rule).c_str(), value.iif);
}
} else {
dw.println("%u %s", key, uidMatchTypeToString(value.rule).c_str());
}
return base::Result<void>();
};
res = mUidOwnerMap.iterateWithValue(printUidMatchInfo);
if (!res.ok()) {
dw.println("mUidOwnerMap print end with error: %s", res.error().message().c_str());
}
} }
} // namespace net } // namespace net

View File

@@ -793,11 +793,6 @@ TEST_F(TrafficControllerTest, TestDumpsys) {
"mCookieTagMap:", "mCookieTagMap:",
fmt::format("cookie={} tag={:#x} uid={}", TEST_COOKIE, TEST_TAG, TEST_UID)}; fmt::format("cookie={} tag={:#x} uid={}", TEST_COOKIE, TEST_TAG, TEST_UID)};
ASSERT_TRUE(isOk(updateUidOwnerMaps({TEST_UID}, HAPPY_BOX_MATCH,
TrafficController::IptOpInsert)));
expectedLines.emplace_back("mUidOwnerMap:");
expectedLines.emplace_back(fmt::format("{} HAPPY_BOX_MATCH", TEST_UID));
EXPECT_TRUE(expectDumpsysContains(expectedLines)); EXPECT_TRUE(expectDumpsysContains(expectedLines));
} }
@@ -815,51 +810,10 @@ TEST_F(TrafficControllerTest, dumpsysInvalidMaps) {
fmt::format("mCookieTagMap {}", kErrIterate), fmt::format("mCookieTagMap {}", kErrIterate),
fmt::format("mIfaceStatsMap {}", kErrIterate), fmt::format("mIfaceStatsMap {}", kErrIterate),
fmt::format("mConfigurationMap {}", kErrReadRulesConfig), fmt::format("mConfigurationMap {}", kErrReadRulesConfig),
fmt::format("mConfigurationMap {}", kErrReadStatsMapConfig), fmt::format("mConfigurationMap {}", kErrReadStatsMapConfig)};
fmt::format("mUidOwnerMap {}", kErrIterate)};
EXPECT_TRUE(expectDumpsysContains(expectedLines)); EXPECT_TRUE(expectDumpsysContains(expectedLines));
} }
TEST_F(TrafficControllerTest, uidMatchTypeToString) {
// NO_MATCH(0) can't be verified because match type flag is added by OR operator.
// See TrafficController::addRule()
static const struct TestConfig {
UidOwnerMatchType uidOwnerMatchType;
std::string expected;
} testConfigs[] = {
// clang-format off
{HAPPY_BOX_MATCH, "HAPPY_BOX_MATCH"},
{DOZABLE_MATCH, "DOZABLE_MATCH"},
{STANDBY_MATCH, "STANDBY_MATCH"},
{POWERSAVE_MATCH, "POWERSAVE_MATCH"},
{HAPPY_BOX_MATCH, "HAPPY_BOX_MATCH"},
{RESTRICTED_MATCH, "RESTRICTED_MATCH"},
{LOW_POWER_STANDBY_MATCH, "LOW_POWER_STANDBY_MATCH"},
{IIF_MATCH, "IIF_MATCH"},
{LOCKDOWN_VPN_MATCH, "LOCKDOWN_VPN_MATCH"},
{OEM_DENY_1_MATCH, "OEM_DENY_1_MATCH"},
{OEM_DENY_2_MATCH, "OEM_DENY_2_MATCH"},
{OEM_DENY_3_MATCH, "OEM_DENY_3_MATCH"},
// clang-format on
};
for (const auto& config : testConfigs) {
SCOPED_TRACE(fmt::format("testConfig: [{}, {}]", config.uidOwnerMatchType,
config.expected));
// Test private function uidMatchTypeToString() via dumpsys.
ASSERT_TRUE(isOk(updateUidOwnerMaps({TEST_UID}, config.uidOwnerMatchType,
TrafficController::IptOpInsert)));
std::vector<std::string> expectedLines;
expectedLines.emplace_back(fmt::format("{} {}", TEST_UID, config.expected));
EXPECT_TRUE(expectDumpsysContains(expectedLines));
// Clean up the stubs.
ASSERT_TRUE(isOk(updateUidOwnerMaps({TEST_UID}, config.uidOwnerMatchType,
TrafficController::IptOpDelete)));
}
}
TEST_F(TrafficControllerTest, getFirewallType) { TEST_F(TrafficControllerTest, getFirewallType) {
static const struct TestConfig { static const struct TestConfig {
ChildChain childChain; ChildChain childChain;

View File

@@ -145,6 +145,20 @@ public class BpfNetMaps {
Pair.create(PERMISSION_INTERNET, "PERMISSION_INTERNET"), Pair.create(PERMISSION_INTERNET, "PERMISSION_INTERNET"),
Pair.create(PERMISSION_UPDATE_DEVICE_STATS, "PERMISSION_UPDATE_DEVICE_STATS") Pair.create(PERMISSION_UPDATE_DEVICE_STATS, "PERMISSION_UPDATE_DEVICE_STATS")
); );
private static final List<Pair<Long, String>> MATCH_LIST = Arrays.asList(
Pair.create(HAPPY_BOX_MATCH, "HAPPY_BOX_MATCH"),
Pair.create(PENALTY_BOX_MATCH, "PENALTY_BOX_MATCH"),
Pair.create(DOZABLE_MATCH, "DOZABLE_MATCH"),
Pair.create(STANDBY_MATCH, "STANDBY_MATCH"),
Pair.create(POWERSAVE_MATCH, "POWERSAVE_MATCH"),
Pair.create(RESTRICTED_MATCH, "RESTRICTED_MATCH"),
Pair.create(LOW_POWER_STANDBY_MATCH, "LOW_POWER_STANDBY_MATCH"),
Pair.create(IIF_MATCH, "IIF_MATCH"),
Pair.create(LOCKDOWN_VPN_MATCH, "LOCKDOWN_VPN_MATCH"),
Pair.create(OEM_DENY_1_MATCH, "OEM_DENY_1_MATCH"),
Pair.create(OEM_DENY_2_MATCH, "OEM_DENY_2_MATCH"),
Pair.create(OEM_DENY_3_MATCH, "OEM_DENY_3_MATCH")
);
/** /**
* Set sEnableJavaBpfMap for test. * Set sEnableJavaBpfMap for test.
@@ -950,6 +964,26 @@ public class BpfNetMaps {
return sj.toString(); return sj.toString();
} }
private String matchToString(long matchMask) {
if (matchMask == NO_MATCH) {
return "NO_MATCH";
}
final StringJoiner sj = new StringJoiner(" ");
for (Pair<Long, String> match: MATCH_LIST) {
final long matchFlag = match.first;
final String matchName = match.second;
if ((matchMask & matchFlag) != 0) {
sj.add(matchName);
matchMask &= ~matchFlag;
}
}
if (matchMask != 0) {
sj.add("UNKNOWN_MATCH(" + matchMask + ")");
}
return sj.toString();
}
/** /**
* Dump BPF maps * Dump BPF maps
* *
@@ -969,6 +1003,15 @@ public class BpfNetMaps {
mDeps.nativeDump(fd, verbose); mDeps.nativeDump(fd, verbose);
if (verbose) { if (verbose) {
BpfDump.dumpMap(sUidOwnerMap, pw, "sUidOwnerMap",
(uid, match) -> {
if ((match.rule & IIF_MATCH) != 0) {
// TODO: convert interface index to interface name by IfaceIndexNameMap
return uid.val + " " + matchToString(match.rule) + " " + match.iif;
} else {
return uid.val + " " + matchToString(match.rule);
}
});
BpfDump.dumpMap(sUidPermissionMap, pw, "sUidPermissionMap", BpfDump.dumpMap(sUidPermissionMap, pw, "sUidPermissionMap",
(uid, permission) -> uid.val + " " + permissionToString(permission.val)); (uid, permission) -> uid.val + " " + permissionToString(permission.val));
} }

View File

@@ -37,10 +37,15 @@ import static com.android.server.BpfNetMaps.DOZABLE_MATCH;
import static com.android.server.BpfNetMaps.HAPPY_BOX_MATCH; import static com.android.server.BpfNetMaps.HAPPY_BOX_MATCH;
import static com.android.server.BpfNetMaps.IIF_MATCH; import static com.android.server.BpfNetMaps.IIF_MATCH;
import static com.android.server.BpfNetMaps.LOCKDOWN_VPN_MATCH; import static com.android.server.BpfNetMaps.LOCKDOWN_VPN_MATCH;
import static com.android.server.BpfNetMaps.LOW_POWER_STANDBY_MATCH;
import static com.android.server.BpfNetMaps.NO_MATCH; import static com.android.server.BpfNetMaps.NO_MATCH;
import static com.android.server.BpfNetMaps.OEM_DENY_1_MATCH;
import static com.android.server.BpfNetMaps.OEM_DENY_2_MATCH;
import static com.android.server.BpfNetMaps.OEM_DENY_3_MATCH;
import static com.android.server.BpfNetMaps.PENALTY_BOX_MATCH; import static com.android.server.BpfNetMaps.PENALTY_BOX_MATCH;
import static com.android.server.BpfNetMaps.POWERSAVE_MATCH; import static com.android.server.BpfNetMaps.POWERSAVE_MATCH;
import static com.android.server.BpfNetMaps.RESTRICTED_MATCH; import static com.android.server.BpfNetMaps.RESTRICTED_MATCH;
import static com.android.server.BpfNetMaps.STANDBY_MATCH;
import static com.android.server.ConnectivityStatsLog.NETWORK_BPF_MAP_INFO; import static com.android.server.ConnectivityStatsLog.NETWORK_BPF_MAP_INFO;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@@ -963,4 +968,53 @@ public final class BpfNetMapsTest {
doTestDumpUidPermissionMap(PERMISSION_INTERNET | 1 << 6, doTestDumpUidPermissionMap(PERMISSION_INTERNET | 1 << 6,
"PERMISSION_INTERNET PERMISSION_UNKNOWN(64)"); "PERMISSION_INTERNET PERMISSION_UNKNOWN(64)");
} }
void doTestDumpUidOwnerMap(final int iif, final long match, final String matchString)
throws Exception {
mUidOwnerMap.updateEntry(new S32(TEST_UID), new UidOwnerValue(iif, match));
assertDumpContains(getDump(), TEST_UID + " " + matchString);
}
void doTestDumpUidOwnerMap(final long match, final String matchString) throws Exception {
doTestDumpUidOwnerMap(0 /* iif */, match, matchString);
}
@Test
@IgnoreUpTo(Build.VERSION_CODES.S_V2)
public void testDumpUidOwnerMap() throws Exception {
doTestDumpUidOwnerMap(HAPPY_BOX_MATCH, "HAPPY_BOX_MATCH");
doTestDumpUidOwnerMap(PENALTY_BOX_MATCH, "PENALTY_BOX_MATCH");
doTestDumpUidOwnerMap(DOZABLE_MATCH, "DOZABLE_MATCH");
doTestDumpUidOwnerMap(STANDBY_MATCH, "STANDBY_MATCH");
doTestDumpUidOwnerMap(POWERSAVE_MATCH, "POWERSAVE_MATCH");
doTestDumpUidOwnerMap(RESTRICTED_MATCH, "RESTRICTED_MATCH");
doTestDumpUidOwnerMap(LOW_POWER_STANDBY_MATCH, "LOW_POWER_STANDBY_MATCH");
doTestDumpUidOwnerMap(LOCKDOWN_VPN_MATCH, "LOCKDOWN_VPN_MATCH");
doTestDumpUidOwnerMap(OEM_DENY_1_MATCH, "OEM_DENY_1_MATCH");
doTestDumpUidOwnerMap(OEM_DENY_2_MATCH, "OEM_DENY_2_MATCH");
doTestDumpUidOwnerMap(OEM_DENY_3_MATCH, "OEM_DENY_3_MATCH");
doTestDumpUidOwnerMap(HAPPY_BOX_MATCH | POWERSAVE_MATCH,
"HAPPY_BOX_MATCH POWERSAVE_MATCH");
doTestDumpUidOwnerMap(DOZABLE_MATCH | LOCKDOWN_VPN_MATCH | OEM_DENY_1_MATCH,
"DOZABLE_MATCH LOCKDOWN_VPN_MATCH OEM_DENY_1_MATCH");
}
@Test
@IgnoreUpTo(Build.VERSION_CODES.S_V2)
public void testDumpUidOwnerMapWithIifMatch() throws Exception {
doTestDumpUidOwnerMap(TEST_IF_INDEX, IIF_MATCH, "IIF_MATCH " + TEST_IF_INDEX);
doTestDumpUidOwnerMap(TEST_IF_INDEX,
IIF_MATCH | DOZABLE_MATCH | LOCKDOWN_VPN_MATCH | OEM_DENY_1_MATCH,
"DOZABLE_MATCH IIF_MATCH LOCKDOWN_VPN_MATCH OEM_DENY_1_MATCH " + TEST_IF_INDEX);
}
@Test
@IgnoreUpTo(Build.VERSION_CODES.S_V2)
public void testDumpUidOwnerMapWithInvalidMatch() throws Exception {
final long invalid_match = 1L << 31;
doTestDumpUidOwnerMap(invalid_match, "UNKNOWN_MATCH(" + invalid_match + ")");
doTestDumpUidOwnerMap(DOZABLE_MATCH | invalid_match,
"DOZABLE_MATCH UNKNOWN_MATCH(" + invalid_match + ")");
}
} }