Add methods for updating ingressDiscardRule bpf map to BpfNetMaps
Bug 295800201
Test: NetworkStaticLibsTests
Change-Id: I42bc0adc22c3018480029d624053f758d815e526
diff --git a/service/src/com/android/server/BpfNetMaps.java b/service/src/com/android/server/BpfNetMaps.java
index 6ade124..ccff9c9 100644
--- a/service/src/com/android/server/BpfNetMaps.java
+++ b/service/src/com/android/server/BpfNetMaps.java
@@ -25,6 +25,7 @@
import static android.net.BpfNetMapsConstants.DATA_SAVER_ENABLED_MAP_PATH;
import static android.net.BpfNetMapsConstants.HAPPY_BOX_MATCH;
import static android.net.BpfNetMapsConstants.IIF_MATCH;
+import static android.net.BpfNetMapsConstants.INGRESS_DISCARD_MAP_PATH;
import static android.net.BpfNetMapsConstants.LOCKDOWN_VPN_MATCH;
import static android.net.BpfNetMapsConstants.PENALTY_BOX_MATCH;
import static android.net.BpfNetMapsConstants.UID_OWNER_MAP_PATH;
@@ -85,9 +86,12 @@
import com.android.net.module.util.Struct.U8;
import com.android.net.module.util.bpf.CookieTagMapKey;
import com.android.net.module.util.bpf.CookieTagMapValue;
+import com.android.net.module.util.bpf.IngressDiscardKey;
+import com.android.net.module.util.bpf.IngressDiscardValue;
import java.io.FileDescriptor;
import java.io.IOException;
+import java.net.InetAddress;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
@@ -136,6 +140,7 @@
private static IBpfMap<CookieTagMapKey, CookieTagMapValue> sCookieTagMap = null;
// TODO: Add BOOL class and replace U8?
private static IBpfMap<S32, U8> sDataSaverEnabledMap = null;
+ private static IBpfMap<IngressDiscardKey, IngressDiscardValue> sIngressDiscardMap = null;
private static final List<Pair<Integer, String>> PERMISSION_LIST = Arrays.asList(
Pair.create(PERMISSION_INTERNET, "PERMISSION_INTERNET"),
@@ -191,6 +196,15 @@
sDataSaverEnabledMap = dataSaverEnabledMap;
}
+ /**
+ * Set ingressDiscardMap for test.
+ */
+ @VisibleForTesting
+ public static void setIngressDiscardMapForTest(
+ IBpfMap<IngressDiscardKey, IngressDiscardValue> ingressDiscardMap) {
+ sIngressDiscardMap = ingressDiscardMap;
+ }
+
private static IBpfMap<S32, U32> getConfigurationMap() {
try {
return new BpfMap<>(
@@ -236,6 +250,15 @@
}
}
+ private static IBpfMap<IngressDiscardKey, IngressDiscardValue> getIngressDiscardMap() {
+ try {
+ return new BpfMap<>(INGRESS_DISCARD_MAP_PATH, BpfMap.BPF_F_RDWR,
+ IngressDiscardKey.class, IngressDiscardValue.class);
+ } catch (ErrnoException e) {
+ throw new IllegalStateException("Cannot open ingress discard map", e);
+ }
+ }
+
private static void initBpfMaps() {
if (sConfigurationMap == null) {
sConfigurationMap = getConfigurationMap();
@@ -278,6 +301,15 @@
} catch (ErrnoException e) {
throw new IllegalStateException("Failed to initialize data saver configuration", e);
}
+
+ if (sIngressDiscardMap == null) {
+ sIngressDiscardMap = getIngressDiscardMap();
+ }
+ try {
+ sIngressDiscardMap.clear();
+ } catch (ErrnoException e) {
+ throw new IllegalStateException("Failed to initialize ingress discard map", e);
+ }
}
/**
@@ -315,6 +347,13 @@
}
/**
+ * Get interface name
+ */
+ public String getIfName(final int ifIndex) {
+ return Os.if_indextoname(ifIndex);
+ }
+
+ /**
* Call synchronize_rcu()
*/
public int synchronizeKernelRCU() {
@@ -575,7 +614,7 @@
private Set<Integer> asSet(final int[] uids) {
final Set<Integer> uidSet = new ArraySet<>();
- for (final int uid: uids) {
+ for (final int uid : uids) {
uidSet.add(uid);
}
return uidSet;
@@ -979,6 +1018,45 @@
}
}
+ /**
+ * Set ingress discard rule
+ *
+ * @param address target address to set the ingress discard rule
+ * @param iface allowed interface
+ */
+ @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+ public void setIngressDiscardRule(final InetAddress address, final String iface) {
+ throwIfPreT("setIngressDiscardRule is not available on pre-T devices");
+ final int ifIndex = mDeps.getIfIndex(iface);
+ if (ifIndex == 0) {
+ Log.e(TAG, "Failed to get if index, skip setting ingress discard rule for " + address
+ + "(" + iface + ")");
+ return;
+ }
+ try {
+ sIngressDiscardMap.updateEntry(new IngressDiscardKey(address),
+ new IngressDiscardValue(ifIndex, ifIndex));
+ } catch (ErrnoException e) {
+ Log.e(TAG, "Failed to set ingress discard rule for " + address + "("
+ + iface + "), " + e);
+ }
+ }
+
+ /**
+ * Remove ingress discard rule
+ *
+ * @param address target address to remove the ingress discard rule
+ */
+ @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+ public void removeIngressDiscardRule(final InetAddress address) {
+ throwIfPreT("removeIngressDiscardRule is not available on pre-T devices");
+ try {
+ sIngressDiscardMap.deleteEntry(new IngressDiscardKey(address));
+ } catch (ErrnoException e) {
+ Log.e(TAG, "Failed to remove ingress discard rule for " + address + ", " + e);
+ }
+ }
+
/** Register callback for statsd to pull atom. */
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
public void setPullAtomCallback(final Context context) {
@@ -1120,7 +1198,10 @@
});
BpfDump.dumpMap(sUidPermissionMap, pw, "sUidPermissionMap",
(uid, permission) -> uid.val + " " + permissionToString(permission.val));
-
+ BpfDump.dumpMap(sIngressDiscardMap, pw, "sIngressDiscardMap",
+ (key, value) -> "[" + key.dstAddr + "]: "
+ + value.iif1 + "(" + mDeps.getIfName(value.iif1) + "), "
+ + value.iif2 + "(" + mDeps.getIfName(value.iif2) + ")");
dumpDataSaverConfig(pw);
pw.decreaseIndent();
}