Merge "updateSupportedDownstreams when tethering allowed is changed"
diff --git a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
index ac0bbd4..05a2884 100644
--- a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
+++ b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
@@ -64,7 +64,7 @@
import com.android.net.module.util.NetworkStackConstants;
import com.android.net.module.util.SharedLog;
import com.android.net.module.util.Struct;
-import com.android.net.module.util.Struct.U32;
+import com.android.net.module.util.Struct.S32;
import com.android.net.module.util.bpf.Tether4Key;
import com.android.net.module.util.bpf.Tether4Value;
import com.android.net.module.util.bpf.TetherStatsKey;
@@ -575,7 +575,7 @@
if (!mBpfCoordinatorShim.startUpstreamIpv6Forwarding(downstream, upstream, rule.srcMac,
NULL_MAC_ADDRESS, NULL_MAC_ADDRESS, NetworkStackConstants.ETHER_MTU)) {
mLog.e("Failed to enable upstream IPv6 forwarding from "
- + mInterfaceNames.get(downstream) + " to " + mInterfaceNames.get(upstream));
+ + getIfName(downstream) + " to " + getIfName(upstream));
}
}
@@ -616,7 +616,7 @@
if (!mBpfCoordinatorShim.stopUpstreamIpv6Forwarding(downstream, upstream,
rule.srcMac)) {
mLog.e("Failed to disable upstream IPv6 forwarding from "
- + mInterfaceNames.get(downstream) + " to " + mInterfaceNames.get(upstream));
+ + getIfName(downstream) + " to " + getIfName(upstream));
}
}
@@ -960,8 +960,12 @@
}
// TODO: make mInterfaceNames accessible to the shim and move this code to there.
- private String getIfName(long ifindex) {
- return mInterfaceNames.get((int) ifindex, Long.toString(ifindex));
+ // This function should only be used for logging/dump purposes.
+ private String getIfName(int ifindex) {
+ // TODO: return something more useful on lookup failure
+ // likely use the 'iface_index_name_map' bpf map and/or if_nametoindex
+ // perhaps should even check that all 3 match if available.
+ return mInterfaceNames.get(ifindex, Integer.toString(ifindex));
}
/**
@@ -1038,8 +1042,8 @@
for (int i = 0; i < mStats.size(); i++) {
final int upstreamIfindex = mStats.keyAt(i);
final ForwardedStats stats = mStats.get(upstreamIfindex);
- pw.println(String.format("%d(%s) - %s", upstreamIfindex, mInterfaceNames.get(
- upstreamIfindex), stats.toString()));
+ pw.println(String.format("%d(%s) - %s", upstreamIfindex, getIfName(upstreamIfindex),
+ stats.toString()));
}
}
private void dumpBpfStats(@NonNull IndentingPrintWriter pw) {
@@ -1082,8 +1086,9 @@
for (Ipv6ForwardingRule rule : rules.values()) {
final int upstreamIfindex = rule.upstreamIfindex;
pw.println(String.format("%d(%s) %d(%s) %s [%s] [%s]", upstreamIfindex,
- mInterfaceNames.get(upstreamIfindex), rule.downstreamIfindex,
- downstreamIface, rule.address.getHostAddress(), rule.srcMac, rule.dstMac));
+ getIfName(upstreamIfindex), rule.downstreamIfindex,
+ getIfName(rule.downstreamIfindex), rule.address.getHostAddress(),
+ rule.srcMac, rule.dstMac));
}
pw.decreaseIndent();
}
@@ -1278,18 +1283,18 @@
pw.println("No counter support");
return;
}
- try (BpfMap<U32, U32> map = new BpfMap<>(TETHER_ERROR_MAP_PATH, BpfMap.BPF_F_RDONLY,
- U32.class, U32.class)) {
+ try (BpfMap<S32, S32> map = new BpfMap<>(TETHER_ERROR_MAP_PATH, BpfMap.BPF_F_RDONLY,
+ S32.class, S32.class)) {
map.forEach((k, v) -> {
String counterName;
try {
- counterName = sBpfCounterNames[(int) k.val];
+ counterName = sBpfCounterNames[k.val];
} catch (IndexOutOfBoundsException e) {
// Should never happen because this code gets the counter name from the same
// include file as the BPF program that increments the counter.
Log.wtf(TAG, "Unknown tethering counter type " + k.val);
- counterName = Long.toString(k.val);
+ counterName = Integer.toString(k.val);
}
if (v.val > 0) pw.println(String.format("%s: %d", counterName, v.val));
});
@@ -1817,8 +1822,7 @@
// TODO: Perhaps stop the coordinator.
boolean success = updateDataLimit(upstreamIfindex);
if (!success) {
- final String iface = mInterfaceNames.get(upstreamIfindex);
- mLog.e("Setting data limit for " + iface + " failed.");
+ mLog.e("Setting data limit for " + getIfName(upstreamIfindex) + " failed.");
}
}
diff --git a/Tethering/src/com/android/networkstack/tethering/TetherDevKey.java b/Tethering/src/com/android/networkstack/tethering/TetherDevKey.java
index 4283c1b..997080c 100644
--- a/Tethering/src/com/android/networkstack/tethering/TetherDevKey.java
+++ b/Tethering/src/com/android/networkstack/tethering/TetherDevKey.java
@@ -22,10 +22,10 @@
/** The key of BpfMap which is used for mapping interface index. */
public class TetherDevKey extends Struct {
- @Field(order = 0, type = Type.U32)
- public final long ifIndex; // interface index
+ @Field(order = 0, type = Type.S32)
+ public final int ifIndex; // interface index
- public TetherDevKey(final long ifIndex) {
+ public TetherDevKey(final int ifIndex) {
this.ifIndex = ifIndex;
}
}
diff --git a/Tethering/src/com/android/networkstack/tethering/TetherDevValue.java b/Tethering/src/com/android/networkstack/tethering/TetherDevValue.java
index 1cd99b5..b6e0c73 100644
--- a/Tethering/src/com/android/networkstack/tethering/TetherDevValue.java
+++ b/Tethering/src/com/android/networkstack/tethering/TetherDevValue.java
@@ -22,10 +22,10 @@
/** The key of BpfMap which is used for mapping interface index. */
public class TetherDevValue extends Struct {
- @Field(order = 0, type = Type.U32)
- public final long ifIndex; // interface index
+ @Field(order = 0, type = Type.S32)
+ public final int ifIndex; // interface index
- public TetherDevValue(final long ifIndex) {
+ public TetherDevValue(final int ifIndex) {
this.ifIndex = ifIndex;
}
}
diff --git a/Tethering/src/com/android/networkstack/tethering/TetherDownstream6Key.java b/Tethering/src/com/android/networkstack/tethering/TetherDownstream6Key.java
index a08ad4a..e34b3f1 100644
--- a/Tethering/src/com/android/networkstack/tethering/TetherDownstream6Key.java
+++ b/Tethering/src/com/android/networkstack/tethering/TetherDownstream6Key.java
@@ -32,8 +32,8 @@
/** The key of BpfMap which is used for bpf offload. */
public class TetherDownstream6Key extends Struct {
- @Field(order = 0, type = Type.U32)
- public final long iif; // The input interface index.
+ @Field(order = 0, type = Type.S32)
+ public final int iif; // The input interface index.
@Field(order = 1, type = Type.EUI48, padding = 2)
public final MacAddress dstMac; // Destination ethernet mac address (zeroed iff rawip ingress).
@@ -41,7 +41,7 @@
@Field(order = 2, type = Type.ByteArray, arraysize = 16)
public final byte[] neigh6; // The destination IPv6 address.
- public TetherDownstream6Key(final long iif, @NonNull final MacAddress dstMac,
+ public TetherDownstream6Key(final int iif, @NonNull final MacAddress dstMac,
final byte[] neigh6) {
Objects.requireNonNull(dstMac);
diff --git a/Tethering/src/com/android/networkstack/tethering/TetherLimitKey.java b/Tethering/src/com/android/networkstack/tethering/TetherLimitKey.java
index bc9bb47..a7e8ccf 100644
--- a/Tethering/src/com/android/networkstack/tethering/TetherLimitKey.java
+++ b/Tethering/src/com/android/networkstack/tethering/TetherLimitKey.java
@@ -22,10 +22,10 @@
/** The key of BpfMap which is used for tethering per-interface limit. */
public class TetherLimitKey extends Struct {
- @Field(order = 0, type = Type.U32)
- public final long ifindex; // upstream interface index
+ @Field(order = 0, type = Type.S32)
+ public final int ifindex; // upstream interface index
- public TetherLimitKey(final long ifindex) {
+ public TetherLimitKey(final int ifindex) {
this.ifindex = ifindex;
}
@@ -43,7 +43,7 @@
@Override
public int hashCode() {
- return Long.hashCode(ifindex);
+ return Integer.hashCode(ifindex);
}
@Override
diff --git a/Tethering/tests/privileged/src/com/android/networkstack/tethering/BpfMapTest.java b/Tethering/tests/privileged/src/com/android/networkstack/tethering/BpfMapTest.java
index 536ab2d..0e8b044 100644
--- a/Tethering/tests/privileged/src/com/android/networkstack/tethering/BpfMapTest.java
+++ b/Tethering/tests/privileged/src/com/android/networkstack/tethering/BpfMapTest.java
@@ -98,7 +98,7 @@
assertTrue(mTestMap.isEmpty());
}
- private TetherDownstream6Key createTetherDownstream6Key(long iif, String mac,
+ private TetherDownstream6Key createTetherDownstream6Key(int iif, String mac,
String address) throws Exception {
final MacAddress dstMac = MacAddress.fromString(mac);
final InetAddress ipv6Address = InetAddress.getByName(address);
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
index 63bb731..b100f58 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
@@ -222,7 +222,7 @@
private static class TestUpstream4Key {
public static class Builder {
- private long mIif = DOWNSTREAM_IFINDEX;
+ private int mIif = DOWNSTREAM_IFINDEX;
private MacAddress mDstMac = DOWNSTREAM_MAC;
private short mL4proto = (short) IPPROTO_TCP;
private byte[] mSrc4 = PRIVATE_ADDR.getAddress();
@@ -246,7 +246,7 @@
private static class TestDownstream4Key {
public static class Builder {
- private long mIif = UPSTREAM_IFINDEX;
+ private int mIif = UPSTREAM_IFINDEX;
private MacAddress mDstMac = MacAddress.ALL_ZEROS_ADDRESS /* dstMac (rawip) */;
private short mL4proto = (short) IPPROTO_TCP;
private byte[] mSrc4 = REMOTE_ADDR.getAddress();
@@ -270,7 +270,7 @@
private static class TestUpstream4Value {
public static class Builder {
- private long mOif = UPSTREAM_IFINDEX;
+ private int mOif = UPSTREAM_IFINDEX;
private MacAddress mEthDstMac = MacAddress.ALL_ZEROS_ADDRESS /* dstMac (rawip) */;
private MacAddress mEthSrcMac = MacAddress.ALL_ZEROS_ADDRESS /* dstMac (rawip) */;
private int mEthProto = ETH_P_IP;
@@ -290,7 +290,7 @@
private static class TestDownstream4Value {
public static class Builder {
- private long mOif = DOWNSTREAM_IFINDEX;
+ private int mOif = DOWNSTREAM_IFINDEX;
private MacAddress mEthDstMac = MAC_A /* client mac */;
private MacAddress mEthSrcMac = DOWNSTREAM_MAC;
private int mEthProto = ETH_P_IP;
@@ -941,11 +941,11 @@
@Test
public void testRuleMakeTetherDownstream6Key() throws Exception {
- final Integer mobileIfIndex = 100;
+ final int mobileIfIndex = 100;
final Ipv6ForwardingRule rule = buildTestForwardingRule(mobileIfIndex, NEIGH_A, MAC_A);
final TetherDownstream6Key key = rule.makeTetherDownstream6Key();
- assertEquals(key.iif, (long) mobileIfIndex);
+ assertEquals(key.iif, mobileIfIndex);
assertEquals(key.dstMac, MacAddress.ALL_ZEROS_ADDRESS); // rawip upstream
assertTrue(Arrays.equals(key.neigh6, NEIGH_A.getAddress()));
// iif (4) + dstMac(6) + padding(2) + neigh6 (16) = 28.
@@ -954,7 +954,7 @@
@Test
public void testRuleMakeTether6Value() throws Exception {
- final Integer mobileIfIndex = 100;
+ final int mobileIfIndex = 100;
final Ipv6ForwardingRule rule = buildTestForwardingRule(mobileIfIndex, NEIGH_A, MAC_A);
final Tether6Value value = rule.makeTether6Value();
@@ -974,7 +974,7 @@
final BpfCoordinator coordinator = makeBpfCoordinator();
final String mobileIface = "rmnet_data0";
- final Integer mobileIfIndex = 100;
+ final int mobileIfIndex = 100;
coordinator.addUpstreamNameToLookupTable(mobileIfIndex, mobileIface);
// [1] Default limit.
@@ -1018,7 +1018,7 @@
final BpfCoordinator coordinator = makeBpfCoordinator();
final String mobileIface = "rmnet_data0";
- final Integer mobileIfIndex = 100;
+ final int mobileIfIndex = 100;
coordinator.addUpstreamNameToLookupTable(mobileIfIndex, mobileIface);
// Applying a data limit to the current upstream does not take any immediate action.
diff --git a/common/src/com/android/net/module/util/bpf/Tether4Key.java b/common/src/com/android/net/module/util/bpf/Tether4Key.java
index 638576f..8273e6a 100644
--- a/common/src/com/android/net/module/util/bpf/Tether4Key.java
+++ b/common/src/com/android/net/module/util/bpf/Tether4Key.java
@@ -30,8 +30,8 @@
/** Key type for downstream & upstream IPv4 forwarding maps. */
public class Tether4Key extends Struct {
- @Field(order = 0, type = Type.U32)
- public final long iif;
+ @Field(order = 0, type = Type.S32)
+ public final int iif;
@Field(order = 1, type = Type.EUI48)
public final MacAddress dstMac;
@@ -51,7 +51,7 @@
@Field(order = 6, type = Type.UBE16)
public final int dstPort;
- public Tether4Key(final long iif, @NonNull final MacAddress dstMac, final short l4proto,
+ public Tether4Key(final int iif, @NonNull final MacAddress dstMac, final short l4proto,
final byte[] src4, final byte[] dst4, final int srcPort,
final int dstPort) {
Objects.requireNonNull(dstMac);
diff --git a/common/src/com/android/net/module/util/bpf/Tether4Value.java b/common/src/com/android/net/module/util/bpf/Tether4Value.java
index de98766..74fdda2 100644
--- a/common/src/com/android/net/module/util/bpf/Tether4Value.java
+++ b/common/src/com/android/net/module/util/bpf/Tether4Value.java
@@ -30,8 +30,8 @@
/** Value type for downstream & upstream IPv4 forwarding maps. */
public class Tether4Value extends Struct {
- @Field(order = 0, type = Type.U32)
- public final long oif;
+ @Field(order = 0, type = Type.S32)
+ public final int oif;
// The ethhdr struct which is defined in uapi/linux/if_ether.h
@Field(order = 1, type = Type.EUI48)
@@ -60,7 +60,7 @@
@Field(order = 9, type = Type.U63)
public final long lastUsed;
- public Tether4Value(final long oif, @NonNull final MacAddress ethDstMac,
+ public Tether4Value(final int oif, @NonNull final MacAddress ethDstMac,
@NonNull final MacAddress ethSrcMac, final int ethProto, final int pmtu,
final byte[] src46, final byte[] dst46, final int srcPort,
final int dstPort, final long lastUsed) {
diff --git a/service/jni/com_android_server_TestNetworkService.cpp b/service/jni/com_android_server_TestNetworkService.cpp
index a1d0310..bd74d54 100644
--- a/service/jni/com_android_server_TestNetworkService.cpp
+++ b/service/jni/com_android_server_TestNetworkService.cpp
@@ -59,7 +59,8 @@
}
}
-static int createTunTapImpl(JNIEnv* env, bool isTun, bool hasCarrier, const char* iface) {
+static int createTunTapImpl(JNIEnv* env, bool isTun, bool hasCarrier, bool setIffMulticast,
+ const char* iface) {
base::unique_fd tun(open("/dev/tun", O_RDWR | O_NONBLOCK));
ifreq ifr{};
@@ -76,8 +77,8 @@
setTunTapCarrierEnabledImpl(env, iface, tun.get(), hasCarrier);
}
- // Mark TAP interfaces as supporting multicast
- if (!isTun) {
+ // Mark some TAP interfaces as supporting multicast
+ if (setIffMulticast && !isTun) {
base::unique_fd inet6CtrlSock(socket(AF_INET6, SOCK_DGRAM, 0));
ifr.ifr_flags = IFF_MULTICAST;
@@ -122,14 +123,14 @@
}
static jint createTunTap(JNIEnv* env, jclass /* clazz */, jboolean isTun,
- jboolean hasCarrier, jstring jIface) {
+ jboolean hasCarrier, jboolean setIffMulticast, jstring jIface) {
ScopedUtfChars iface(env, jIface);
if (!iface.c_str()) {
jniThrowNullPointerException(env, "iface");
return -1;
}
- return createTunTapImpl(env, isTun, hasCarrier, iface.c_str());
+ return createTunTapImpl(env, isTun, hasCarrier, setIffMulticast, iface.c_str());
}
static void bringUpInterface(JNIEnv* env, jclass /* clazz */, jstring jIface) {
@@ -145,7 +146,7 @@
static const JNINativeMethod gMethods[] = {
{"nativeSetTunTapCarrierEnabled", "(Ljava/lang/String;IZ)V", (void*)setTunTapCarrierEnabled},
- {"nativeCreateTunTap", "(ZZLjava/lang/String;)I", (void*)createTunTap},
+ {"nativeCreateTunTap", "(ZZZLjava/lang/String;)I", (void*)createTunTap},
{"nativeBringUpInterface", "(Ljava/lang/String;)V", (void*)bringUpInterface},
};
diff --git a/service/src/com/android/server/BpfNetMaps.java b/service/src/com/android/server/BpfNetMaps.java
index 594223c..231a47f 100644
--- a/service/src/com/android/server/BpfNetMaps.java
+++ b/service/src/com/android/server/BpfNetMaps.java
@@ -26,6 +26,8 @@
import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY;
import static android.net.ConnectivityManager.FIREWALL_RULE_ALLOW;
import static android.net.ConnectivityManager.FIREWALL_RULE_DENY;
+import static android.net.INetd.PERMISSION_INTERNET;
+import static android.net.INetd.PERMISSION_UNINSTALLED;
import static android.system.OsConstants.EINVAL;
import static android.system.OsConstants.ENODEV;
import static android.system.OsConstants.ENOENT;
@@ -45,6 +47,7 @@
import com.android.net.module.util.BpfMap;
import com.android.net.module.util.DeviceConfigUtils;
import com.android.net.module.util.Struct.U32;
+import com.android.net.module.util.Struct.U8;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -85,6 +88,8 @@
"/sys/fs/bpf/netd_shared/map_netd_configuration_map";
private static final String UID_OWNER_MAP_PATH =
"/sys/fs/bpf/netd_shared/map_netd_uid_owner_map";
+ private static final String UID_PERMISSION_MAP_PATH =
+ "/sys/fs/bpf/netd_shared/map_netd_uid_permission_map";
private static final U32 UID_RULES_CONFIGURATION_KEY = new U32(0);
private static final U32 CURRENT_STATS_MAP_CONFIGURATION_KEY = new U32(1);
private static final long UID_RULES_DEFAULT_CONFIGURATION = 0;
@@ -94,6 +99,7 @@
private static BpfMap<U32, U32> sConfigurationMap = null;
// BpfMap for UID_OWNER_MAP_PATH. This map is not accessed by others.
private static BpfMap<U32, UidOwnerValue> sUidOwnerMap = null;
+ private static BpfMap<U32, U8> sUidPermissionMap = null;
// LINT.IfChange(match_type)
@VisibleForTesting public static final long NO_MATCH = 0;
@@ -135,6 +141,14 @@
sUidOwnerMap = uidOwnerMap;
}
+ /**
+ * Set uidPermissionMap for test.
+ */
+ @VisibleForTesting
+ public static void setUidPermissionMapForTest(BpfMap<U32, U8> uidPermissionMap) {
+ sUidPermissionMap = uidPermissionMap;
+ }
+
private static BpfMap<U32, U32> getConfigurationMap() {
try {
return new BpfMap<>(
@@ -153,6 +167,15 @@
}
}
+ private static BpfMap<U32, U8> getUidPermissionMap() {
+ try {
+ return new BpfMap<>(
+ UID_PERMISSION_MAP_PATH, BpfMap.BPF_F_RDWR, U32.class, U8.class);
+ } catch (ErrnoException e) {
+ throw new IllegalStateException("Cannot open uid permission map", e);
+ }
+ }
+
private static void initBpfMaps() {
if (sConfigurationMap == null) {
sConfigurationMap = getConfigurationMap();
@@ -178,6 +201,10 @@
} catch (ErrnoException e) {
throw new IllegalStateException("Failed to initialize uid owner map", e);
}
+
+ if (sUidPermissionMap == null) {
+ sUidPermissionMap = getUidPermissionMap();
+ }
}
/**
@@ -719,7 +746,31 @@
mNetd.trafficSetNetPermForUids(permissions, uids);
return;
}
- native_setPermissionForUids(permissions, uids);
+
+ if (sEnableJavaBpfMap) {
+ // Remove the entry if package is uninstalled or uid has only INTERNET permission.
+ if (permissions == PERMISSION_UNINSTALLED || permissions == PERMISSION_INTERNET) {
+ for (final int uid : uids) {
+ try {
+ sUidPermissionMap.deleteEntry(new U32(uid));
+ } catch (ErrnoException e) {
+ Log.e(TAG, "Failed to remove uid " + uid + " from permission map: " + e);
+ }
+ }
+ return;
+ }
+
+ for (final int uid : uids) {
+ try {
+ sUidPermissionMap.updateEntry(new U32(uid), new U8((short) permissions));
+ } catch (ErrnoException e) {
+ Log.e(TAG, "Failed to set permission "
+ + permissions + " to uid " + uid + ": " + e);
+ }
+ }
+ } else {
+ native_setPermissionForUids(permissions, uids);
+ }
}
/**
diff --git a/service/src/com/android/server/TestNetworkService.java b/service/src/com/android/server/TestNetworkService.java
index 15d9f13..5549fbe 100644
--- a/service/src/com/android/server/TestNetworkService.java
+++ b/service/src/com/android/server/TestNetworkService.java
@@ -77,7 +77,7 @@
// Native method stubs
private static native int nativeCreateTunTap(boolean isTun, boolean hasCarrier,
- @NonNull String iface);
+ boolean setIffMulticast, @NonNull String iface);
private static native void nativeSetTunTapCarrierEnabled(@NonNull String iface, int tunFd,
boolean enabled);
@@ -136,8 +136,14 @@
final long token = Binder.clearCallingIdentity();
try {
+ // Note: if the interface is brought up by ethernet, setting IFF_MULTICAST
+ // races NetUtils#setInterfaceUp(). This flag is not necessary for ethernet
+ // tests, so let's not set it when bringUp is false. See also b/242343156.
+ // In the future, we could use RTM_SETLINK with ifi_change set to set the
+ // flags atomically.
+ final boolean setIffMulticast = bringUp;
ParcelFileDescriptor tunIntf = ParcelFileDescriptor.adoptFd(
- nativeCreateTunTap(isTun, hasCarrier, interfaceName));
+ nativeCreateTunTap(isTun, hasCarrier, setIffMulticast, interfaceName));
// Disable DAD and remove router_solicitation_delay before assigning link addresses.
if (disableIpv6ProvisioningDelay) {
diff --git a/tests/cts/net/src/android/net/cts/DscpPolicyTest.kt b/tests/cts/net/src/android/net/cts/DscpPolicyTest.kt
index 1f76773..043a0ad 100644
--- a/tests/cts/net/src/android/net/cts/DscpPolicyTest.kt
+++ b/tests/cts/net/src/android/net/cts/DscpPolicyTest.kt
@@ -163,8 +163,7 @@
// Only statically configure the IPv4 address; for IPv6, use the SLAAC generated
// address.
- iface = tnm.createTapInterface(true /* disableIpv6ProvisioningDelay */,
- arrayOf(LinkAddress(LOCAL_IPV4_ADDRESS, IP4_PREFIX_LEN)))
+ iface = tnm.createTapInterface(arrayOf(LinkAddress(LOCAL_IPV4_ADDRESS, IP4_PREFIX_LEN)))
assertNotNull(iface)
}
@@ -224,7 +223,7 @@
val onLinkPrefix = raResponder.prefix
val startTime = SystemClock.elapsedRealtime()
while (SystemClock.elapsedRealtime() - startTime < PACKET_TIMEOUT_MS) {
- SystemClock.sleep(1 /* ms */)
+ SystemClock.sleep(50 /* ms */)
val sock = Os.socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)
try {
network.bindSocket(sock)
@@ -273,7 +272,6 @@
val lp = LinkProperties().apply {
addLinkAddress(LinkAddress(LOCAL_IPV4_ADDRESS, IP4_PREFIX_LEN))
addRoute(RouteInfo(IpPrefix("0.0.0.0/0"), null, null))
- addRoute(RouteInfo(IpPrefix("::/0"), TEST_ROUTER_IPV6_ADDR))
setInterfaceName(specifier)
}
val config = NetworkAgentConfig.Builder().build()
diff --git a/tests/integration/AndroidManifest.xml b/tests/integration/AndroidManifest.xml
index 2e13689..50f02d3 100644
--- a/tests/integration/AndroidManifest.xml
+++ b/tests/integration/AndroidManifest.xml
@@ -60,7 +60,7 @@
<action android:name=".INetworkStackInstrumentation"/>
</intent-filter>
</service>
- <service android:name="com.android.server.connectivity.ipmemorystore.RegularMaintenanceJobService"
+ <service android:name="com.android.networkstack.ipmemorystore.RegularMaintenanceJobService"
android:process="com.android.server.net.integrationtests.testnetworkstack"
android:permission="android.permission.BIND_JOB_SERVICE"/>
diff --git a/tests/unit/java/com/android/server/BpfNetMapsTest.java b/tests/unit/java/com/android/server/BpfNetMapsTest.java
index 2d09bf2..7696c40 100644
--- a/tests/unit/java/com/android/server/BpfNetMapsTest.java
+++ b/tests/unit/java/com/android/server/BpfNetMapsTest.java
@@ -27,6 +27,9 @@
import static android.net.ConnectivityManager.FIREWALL_RULE_ALLOW;
import static android.net.ConnectivityManager.FIREWALL_RULE_DENY;
import static android.net.INetd.PERMISSION_INTERNET;
+import static android.net.INetd.PERMISSION_NONE;
+import static android.net.INetd.PERMISSION_UNINSTALLED;
+import static android.net.INetd.PERMISSION_UPDATE_DEVICE_STATS;
import static com.android.server.BpfNetMaps.DOZABLE_MATCH;
import static com.android.server.BpfNetMaps.HAPPY_BOX_MATCH;
@@ -56,6 +59,7 @@
import com.android.modules.utils.build.SdkLevel;
import com.android.net.module.util.BpfMap;
import com.android.net.module.util.Struct.U32;
+import com.android.net.module.util.Struct.U8;
import com.android.testutils.DevSdkIgnoreRule;
import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter;
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
@@ -107,6 +111,7 @@
private final BpfMap<U32, U32> mConfigurationMap = new TestBpfMap<>(U32.class, U32.class);
private final BpfMap<U32, UidOwnerValue> mUidOwnerMap =
new TestBpfMap<>(U32.class, UidOwnerValue.class);
+ private final BpfMap<U32, U8> mUidPermissionMap = new TestBpfMap<>(U32.class, U8.class);
@Before
public void setUp() throws Exception {
@@ -115,6 +120,7 @@
BpfNetMaps.setEnableJavaBpfMapForTest(true /* enable */);
BpfNetMaps.setConfigurationMapForTest(mConfigurationMap);
BpfNetMaps.setUidOwnerMapForTest(mUidOwnerMap);
+ BpfNetMaps.setUidPermissionMapForTest(mUidPermissionMap);
mBpfNetMaps = new BpfNetMaps(mContext, mNetd, mDeps);
}
@@ -728,4 +734,116 @@
() -> mBpfNetMaps.replaceUidChain(FIREWALL_CHAIN_DOZABLE, TEST_UIDS));
}
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+ public void testSetNetPermForUidsGrantInternetPermission() throws Exception {
+ mBpfNetMaps.setNetPermForUids(PERMISSION_INTERNET, TEST_UIDS);
+
+ assertTrue(mUidPermissionMap.isEmpty());
+ }
+
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+ public void testSetNetPermForUidsGrantUpdateStatsPermission() throws Exception {
+ mBpfNetMaps.setNetPermForUids(PERMISSION_UPDATE_DEVICE_STATS, TEST_UIDS);
+
+ final int uid0 = TEST_UIDS[0];
+ final int uid1 = TEST_UIDS[1];
+ assertEquals(PERMISSION_UPDATE_DEVICE_STATS, mUidPermissionMap.getValue(new U32(uid0)).val);
+ assertEquals(PERMISSION_UPDATE_DEVICE_STATS, mUidPermissionMap.getValue(new U32(uid1)).val);
+ }
+
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+ public void testSetNetPermForUidsGrantMultiplePermissions() throws Exception {
+ final int permission = PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS;
+ mBpfNetMaps.setNetPermForUids(permission, TEST_UIDS);
+
+ final int uid0 = TEST_UIDS[0];
+ final int uid1 = TEST_UIDS[1];
+ assertEquals(permission, mUidPermissionMap.getValue(new U32(uid0)).val);
+ assertEquals(permission, mUidPermissionMap.getValue(new U32(uid1)).val);
+ }
+
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+ public void testSetNetPermForUidsRevokeInternetPermission() throws Exception {
+ final int uid0 = TEST_UIDS[0];
+ final int uid1 = TEST_UIDS[1];
+ mBpfNetMaps.setNetPermForUids(PERMISSION_INTERNET, TEST_UIDS);
+ mBpfNetMaps.setNetPermForUids(PERMISSION_NONE, new int[]{uid0});
+
+ assertEquals(PERMISSION_NONE, mUidPermissionMap.getValue(new U32(uid0)).val);
+ assertNull(mUidPermissionMap.getValue(new U32(uid1)));
+ }
+
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+ public void testSetNetPermForUidsRevokeUpdateDeviceStatsPermission() throws Exception {
+ final int uid0 = TEST_UIDS[0];
+ final int uid1 = TEST_UIDS[1];
+ mBpfNetMaps.setNetPermForUids(PERMISSION_UPDATE_DEVICE_STATS, TEST_UIDS);
+ mBpfNetMaps.setNetPermForUids(PERMISSION_NONE, new int[]{uid0});
+
+ assertEquals(PERMISSION_NONE, mUidPermissionMap.getValue(new U32(uid0)).val);
+ assertEquals(PERMISSION_UPDATE_DEVICE_STATS, mUidPermissionMap.getValue(new U32(uid1)).val);
+ }
+
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+ public void testSetNetPermForUidsRevokeMultiplePermissions() throws Exception {
+ final int uid0 = TEST_UIDS[0];
+ final int uid1 = TEST_UIDS[1];
+ final int permission = PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS;
+ mBpfNetMaps.setNetPermForUids(permission, TEST_UIDS);
+ mBpfNetMaps.setNetPermForUids(PERMISSION_NONE, new int[]{uid0});
+
+ assertEquals(PERMISSION_NONE, mUidPermissionMap.getValue(new U32(uid0)).val);
+ assertEquals(permission, mUidPermissionMap.getValue(new U32(uid1)).val);
+ }
+
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+ public void testSetNetPermForUidsPermissionUninstalled() throws Exception {
+ final int uid0 = TEST_UIDS[0];
+ final int uid1 = TEST_UIDS[1];
+ final int permission = PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS;
+ mBpfNetMaps.setNetPermForUids(permission, TEST_UIDS);
+ mBpfNetMaps.setNetPermForUids(PERMISSION_UNINSTALLED, new int[]{uid0});
+
+ assertNull(mUidPermissionMap.getValue(new U32(uid0)));
+ assertEquals(permission, mUidPermissionMap.getValue(new U32(uid1)).val);
+ }
+
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+ public void testSetNetPermForUidsDuplicatedRequestSilentlyIgnored() throws Exception {
+ final int uid0 = TEST_UIDS[0];
+ final int uid1 = TEST_UIDS[1];
+ final int permission = PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS;
+
+ mBpfNetMaps.setNetPermForUids(permission, TEST_UIDS);
+ assertEquals(permission, mUidPermissionMap.getValue(new U32(uid0)).val);
+ assertEquals(permission, mUidPermissionMap.getValue(new U32(uid1)).val);
+
+ mBpfNetMaps.setNetPermForUids(permission, TEST_UIDS);
+ assertEquals(permission, mUidPermissionMap.getValue(new U32(uid0)).val);
+ assertEquals(permission, mUidPermissionMap.getValue(new U32(uid1)).val);
+
+ mBpfNetMaps.setNetPermForUids(PERMISSION_NONE, TEST_UIDS);
+ assertEquals(PERMISSION_NONE, mUidPermissionMap.getValue(new U32(uid0)).val);
+ assertEquals(PERMISSION_NONE, mUidPermissionMap.getValue(new U32(uid1)).val);
+
+ mBpfNetMaps.setNetPermForUids(PERMISSION_NONE, TEST_UIDS);
+ assertEquals(PERMISSION_NONE, mUidPermissionMap.getValue(new U32(uid0)).val);
+ assertEquals(PERMISSION_NONE, mUidPermissionMap.getValue(new U32(uid1)).val);
+
+ mBpfNetMaps.setNetPermForUids(PERMISSION_UNINSTALLED, TEST_UIDS);
+ assertNull(mUidPermissionMap.getValue(new U32(uid0)));
+ assertNull(mUidPermissionMap.getValue(new U32(uid1)));
+
+ mBpfNetMaps.setNetPermForUids(PERMISSION_UNINSTALLED, TEST_UIDS);
+ assertNull(mUidPermissionMap.getValue(new U32(uid0)));
+ assertNull(mUidPermissionMap.getValue(new U32(uid1)));
+ }
}
diff --git a/tests/unit/java/com/android/server/connectivity/VpnTest.java b/tests/unit/java/com/android/server/connectivity/VpnTest.java
index 041e4ea..f159859 100644
--- a/tests/unit/java/com/android/server/connectivity/VpnTest.java
+++ b/tests/unit/java/com/android/server/connectivity/VpnTest.java
@@ -92,6 +92,7 @@
import android.net.LinkProperties;
import android.net.LocalSocket;
import android.net.Network;
+import android.net.NetworkAgentConfig;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo.DetailedState;
import android.net.RouteInfo;
@@ -264,6 +265,7 @@
final Ikev2VpnProfile.Builder builder =
new Ikev2VpnProfile.Builder(TEST_VPN_SERVER, TEST_VPN_IDENTITY);
builder.setAuthPsk(TEST_VPN_PSK);
+ builder.setBypassable(true /* isBypassable */);
mVpnProfile = builder.build().toVpnProfile();
}
@@ -1787,9 +1789,11 @@
ArgumentCaptor<LinkProperties> lpCaptor = ArgumentCaptor.forClass(LinkProperties.class);
ArgumentCaptor<NetworkCapabilities> ncCaptor =
ArgumentCaptor.forClass(NetworkCapabilities.class);
+ ArgumentCaptor<NetworkAgentConfig> nacCaptor =
+ ArgumentCaptor.forClass(NetworkAgentConfig.class);
verify(mTestDeps).newNetworkAgent(
any(), any(), anyString(), ncCaptor.capture(), lpCaptor.capture(),
- any(), any(), any());
+ any(), nacCaptor.capture(), any());
// Check LinkProperties
final LinkProperties lp = lpCaptor.getValue();
@@ -1811,6 +1815,9 @@
// Check NetworkCapabilities
assertEquals(Arrays.asList(TEST_NETWORK), ncCaptor.getValue().getUnderlyingNetworks());
+ // Check if allowBypass is set or not.
+ assertTrue(nacCaptor.getValue().isBypassableVpn());
+
return new PlatformVpnSnapshot(vpn, nwCb, ikeCb, childCb);
}
diff --git a/tools/gen_jarjar.py b/tools/gen_jarjar.py
index 4c2cf54..2ff53fa 100755
--- a/tools/gen_jarjar.py
+++ b/tools/gen_jarjar.py
@@ -115,7 +115,8 @@
jar_classes = _list_jar_classes(jar)
jar_classes.sort()
for clazz in jar_classes:
- if (_get_toplevel_class(clazz) not in excluded_classes and
+ if (not clazz.startswith(args.prefix + '.') and
+ _get_toplevel_class(clazz) not in excluded_classes and
not any(r.fullmatch(clazz) for r in exclude_regexes)):
outfile.write(f'rule {clazz} {args.prefix}.@0\n')
# Also include jarjar rules for unit tests of the class, so the package matches
diff --git a/tools/testdata/java/jarjar/prefix/AlreadyInTargetPackageClass.java b/tools/testdata/java/jarjar/prefix/AlreadyInTargetPackageClass.java
new file mode 100644
index 0000000..6859020
--- /dev/null
+++ b/tools/testdata/java/jarjar/prefix/AlreadyInTargetPackageClass.java
@@ -0,0 +1,25 @@
+/*
+ * 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 jarjar.prefix;
+
+/**
+ * Sample class to test jarjar rules, already in the "jarjar.prefix" package.
+ */
+public class AlreadyInTargetPackageClass {
+ /** Test inner class that should not be jarjared either */
+ public static class TestInnerClass {}
+}