Merge "ClatCoordinator: use Java class TcUtils to attach program" am: 932459748a
Original change: https://android-review.googlesource.com/c/platform/packages/modules/Connectivity/+/2028287 Change-Id: I2a02006cfe6c21c476af8e350527321851a7043f Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
committed by
Automerger Merge Worker
commit
77487413aa
@@ -404,15 +404,6 @@ static jint com_android_server_connectivity_ClatCoordinator_startClatd(
|
|||||||
posix_spawnattr_destroy(&attr);
|
posix_spawnattr_destroy(&attr);
|
||||||
posix_spawn_file_actions_destroy(&fa);
|
posix_spawn_file_actions_destroy(&fa);
|
||||||
|
|
||||||
// 6. Start BPF if any
|
|
||||||
if (!net::clat::initMaps()) {
|
|
||||||
net::clat::ClatdTracker tracker = {};
|
|
||||||
if (!initTracker(ifaceStr.c_str(), pfx96Str.c_str(), v4Str.c_str(), v6Str.c_str(),
|
|
||||||
&tracker)) {
|
|
||||||
net::clat::maybeStartBpf(tracker);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ package com.android.server.connectivity;
|
|||||||
|
|
||||||
import static android.net.INetd.IF_STATE_UP;
|
import static android.net.INetd.IF_STATE_UP;
|
||||||
import static android.net.INetd.PERMISSION_SYSTEM;
|
import static android.net.INetd.PERMISSION_SYSTEM;
|
||||||
|
import static android.system.OsConstants.ETH_P_IP;
|
||||||
|
import static android.system.OsConstants.ETH_P_IPV6;
|
||||||
|
|
||||||
import static com.android.net.module.util.NetworkStackConstants.IPV6_MIN_MTU;
|
import static com.android.net.module.util.NetworkStackConstants.IPV6_MIN_MTU;
|
||||||
|
|
||||||
@@ -80,6 +82,20 @@ public class ClatCoordinator {
|
|||||||
|
|
||||||
private static final int INVALID_IFINDEX = 0;
|
private static final int INVALID_IFINDEX = 0;
|
||||||
|
|
||||||
|
// For better code clarity when used for 'bool ingress' parameter.
|
||||||
|
@VisibleForTesting
|
||||||
|
static final boolean EGRESS = false;
|
||||||
|
@VisibleForTesting
|
||||||
|
static final boolean INGRESS = true;
|
||||||
|
|
||||||
|
// For better code clarity when used for 'bool ether' parameter.
|
||||||
|
static final boolean RAWIP = false;
|
||||||
|
static final boolean ETHER = true;
|
||||||
|
|
||||||
|
// The priority of clat hook - must be after tethering.
|
||||||
|
@VisibleForTesting
|
||||||
|
static final int PRIO_CLAT = 4;
|
||||||
|
|
||||||
private static final String CLAT_EGRESS4_MAP_PATH = makeMapPath("egress4");
|
private static final String CLAT_EGRESS4_MAP_PATH = makeMapPath("egress4");
|
||||||
private static final String CLAT_INGRESS6_MAP_PATH = makeMapPath("ingress6");
|
private static final String CLAT_INGRESS6_MAP_PATH = makeMapPath("ingress6");
|
||||||
|
|
||||||
@@ -87,6 +103,14 @@ public class ClatCoordinator {
|
|||||||
return "/sys/fs/bpf/map_clatd_clat_" + which + "_map";
|
return "/sys/fs/bpf/map_clatd_clat_" + which + "_map";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String makeProgPath(boolean ingress, boolean ether) {
|
||||||
|
String path = "/sys/fs/bpf/prog_clatd_schedcls_"
|
||||||
|
+ (ingress ? "ingress6" : "egress4")
|
||||||
|
+ "_clat_"
|
||||||
|
+ (ether ? "ether" : "rawip");
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private final INetd mNetd;
|
private final INetd mNetd;
|
||||||
@NonNull
|
@NonNull
|
||||||
@@ -254,6 +278,23 @@ public class ClatCoordinator {
|
|||||||
public boolean isEthernet(String iface) throws IOException {
|
public boolean isEthernet(String iface) throws IOException {
|
||||||
return TcUtils.isEthernet(iface);
|
return TcUtils.isEthernet(iface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Add a clsact qdisc. */
|
||||||
|
public void tcQdiscAddDevClsact(int ifIndex) throws IOException {
|
||||||
|
TcUtils.tcQdiscAddDevClsact(ifIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Attach a tc bpf filter. */
|
||||||
|
public void tcFilterAddDevBpf(int ifIndex, boolean ingress, short prio, short proto,
|
||||||
|
String bpfProgPath) throws IOException {
|
||||||
|
TcUtils.tcFilterAddDevBpf(ifIndex, ingress, prio, proto, bpfProgPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Delete a tc filter. */
|
||||||
|
public void tcFilterDelDev(int ifIndex, boolean ingress, short prio, short proto)
|
||||||
|
throws IOException {
|
||||||
|
TcUtils.tcFilterDelDev(ifIndex, ingress, prio, proto);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -370,7 +411,86 @@ public class ClatCoordinator {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: attach program.
|
// Usually the clsact will be added in netd RouteController::addInterfaceToPhysicalNetwork.
|
||||||
|
// But clat is started before the v4- interface is added to the network. The clat startup
|
||||||
|
// have to add clsact of v4- tun interface first for adding bpf filter in maybeStartBpf.
|
||||||
|
try {
|
||||||
|
// tc qdisc add dev .. clsact
|
||||||
|
mDeps.tcQdiscAddDevClsact(tracker.v4ifIndex);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, "tc qdisc add dev (" + tracker.v4ifIndex + "[" + tracker.v4iface
|
||||||
|
+ "]) failure: " + e);
|
||||||
|
try {
|
||||||
|
mEgressMap.deleteEntry(txKey);
|
||||||
|
} catch (ErrnoException | IllegalStateException e2) {
|
||||||
|
Log.e(TAG, "Could not delete entry (" + txKey + ") from egress map: " + e2);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
mIngressMap.deleteEntry(rxKey);
|
||||||
|
} catch (ErrnoException | IllegalStateException e3) {
|
||||||
|
Log.e(TAG, "Could not delete entry (" + rxKey + ") from ingress map: " + e3);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This program will be attached to the v4-* interface which is a TUN and thus always rawip.
|
||||||
|
try {
|
||||||
|
// tc filter add dev .. egress prio 4 protocol ip bpf object-pinned /sys/fs/bpf/...
|
||||||
|
// direct-action
|
||||||
|
mDeps.tcFilterAddDevBpf(tracker.v4ifIndex, EGRESS, (short) PRIO_CLAT, (short) ETH_P_IP,
|
||||||
|
makeProgPath(EGRESS, RAWIP));
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, "tc filter add dev (" + tracker.v4ifIndex + "[" + tracker.v4iface
|
||||||
|
+ "]) egress prio PRIO_CLAT protocol ip failure: " + e);
|
||||||
|
|
||||||
|
// The v4- interface clsact is not deleted for unwinding error because once it is
|
||||||
|
// created with interface addition, the lifetime is till interface deletion. Moreover,
|
||||||
|
// the clsact has no clat filter now. It should not break anything.
|
||||||
|
|
||||||
|
try {
|
||||||
|
mEgressMap.deleteEntry(txKey);
|
||||||
|
} catch (ErrnoException | IllegalStateException e2) {
|
||||||
|
Log.e(TAG, "Could not delete entry (" + txKey + ") from egress map: " + e2);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
mIngressMap.deleteEntry(rxKey);
|
||||||
|
} catch (ErrnoException | IllegalStateException e3) {
|
||||||
|
Log.e(TAG, "Could not delete entry (" + rxKey + ") from ingress map: " + e3);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// tc filter add dev .. ingress prio 4 protocol ipv6 bpf object-pinned /sys/fs/bpf/...
|
||||||
|
// direct-action
|
||||||
|
mDeps.tcFilterAddDevBpf(tracker.ifIndex, INGRESS, (short) PRIO_CLAT,
|
||||||
|
(short) ETH_P_IPV6, makeProgPath(INGRESS, isEthernet));
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, "tc filter add dev (" + tracker.ifIndex + "[" + tracker.iface
|
||||||
|
+ "]) ingress prio PRIO_CLAT protocol ipv6 failure: " + e);
|
||||||
|
|
||||||
|
// The v4- interface clsact is not deleted. See the reason in the error unwinding code
|
||||||
|
// of the egress filter attaching of v4- tun interface.
|
||||||
|
|
||||||
|
try {
|
||||||
|
mDeps.tcFilterDelDev(tracker.v4ifIndex, EGRESS, (short) PRIO_CLAT,
|
||||||
|
(short) ETH_P_IP);
|
||||||
|
} catch (IOException e2) {
|
||||||
|
Log.e(TAG, "tc filter del dev (" + tracker.v4ifIndex + "[" + tracker.v4iface
|
||||||
|
+ "]) egress prio PRIO_CLAT protocol ip failure: " + e2);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
mEgressMap.deleteEntry(txKey);
|
||||||
|
} catch (ErrnoException | IllegalStateException e3) {
|
||||||
|
Log.e(TAG, "Could not delete entry (" + txKey + ") from egress map: " + e3);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
mIngressMap.deleteEntry(rxKey);
|
||||||
|
} catch (ErrnoException | IllegalStateException e4) {
|
||||||
|
Log.e(TAG, "Could not delete entry (" + rxKey + ") from ingress map: " + e4);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -17,11 +17,16 @@
|
|||||||
package com.android.server.connectivity;
|
package com.android.server.connectivity;
|
||||||
|
|
||||||
import static android.net.INetd.IF_STATE_UP;
|
import static android.net.INetd.IF_STATE_UP;
|
||||||
|
import static android.system.OsConstants.ETH_P_IP;
|
||||||
|
import static android.system.OsConstants.ETH_P_IPV6;
|
||||||
|
|
||||||
import static com.android.net.module.util.NetworkStackConstants.ETHER_MTU;
|
import static com.android.net.module.util.NetworkStackConstants.ETHER_MTU;
|
||||||
import static com.android.server.connectivity.ClatCoordinator.CLAT_MAX_MTU;
|
import static com.android.server.connectivity.ClatCoordinator.CLAT_MAX_MTU;
|
||||||
|
import static com.android.server.connectivity.ClatCoordinator.EGRESS;
|
||||||
|
import static com.android.server.connectivity.ClatCoordinator.INGRESS;
|
||||||
import static com.android.server.connectivity.ClatCoordinator.INIT_V4ADDR_PREFIX_LEN;
|
import static com.android.server.connectivity.ClatCoordinator.INIT_V4ADDR_PREFIX_LEN;
|
||||||
import static com.android.server.connectivity.ClatCoordinator.INIT_V4ADDR_STRING;
|
import static com.android.server.connectivity.ClatCoordinator.INIT_V4ADDR_STRING;
|
||||||
|
import static com.android.server.connectivity.ClatCoordinator.PRIO_CLAT;
|
||||||
import static com.android.testutils.MiscAsserts.assertThrows;
|
import static com.android.testutils.MiscAsserts.assertThrows;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
@@ -103,6 +108,10 @@ public class ClatCoordinatorTest {
|
|||||||
private static final ParcelFileDescriptor PACKET_SOCK_PFD = new ParcelFileDescriptor(
|
private static final ParcelFileDescriptor PACKET_SOCK_PFD = new ParcelFileDescriptor(
|
||||||
new FileDescriptor());
|
new FileDescriptor());
|
||||||
|
|
||||||
|
private static final String EGRESS_PROG_PATH =
|
||||||
|
"/sys/fs/bpf/prog_clatd_schedcls_egress4_clat_rawip";
|
||||||
|
private static final String INGRESS_PROG_PATH =
|
||||||
|
"/sys/fs/bpf/prog_clatd_schedcls_ingress6_clat_ether";
|
||||||
private static final ClatEgress4Key EGRESS_KEY = new ClatEgress4Key(STACKED_IFINDEX,
|
private static final ClatEgress4Key EGRESS_KEY = new ClatEgress4Key(STACKED_IFINDEX,
|
||||||
INET4_LOCAL4);
|
INET4_LOCAL4);
|
||||||
private static final ClatEgress4Value EGRESS_VALUE = new ClatEgress4Value(BASE_IFINDEX,
|
private static final ClatEgress4Value EGRESS_VALUE = new ClatEgress4Value(BASE_IFINDEX,
|
||||||
@@ -334,6 +343,29 @@ public class ClatCoordinatorTest {
|
|||||||
fail("unsupported arg: " + iface);
|
fail("unsupported arg: " + iface);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Add a clsact qdisc. */
|
||||||
|
@Override
|
||||||
|
public void tcQdiscAddDevClsact(int ifIndex) throws IOException {
|
||||||
|
// no-op
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Attach a tc bpf filter. */
|
||||||
|
@Override
|
||||||
|
public void tcFilterAddDevBpf(int ifIndex, boolean ingress, short prio, short proto,
|
||||||
|
String bpfProgPath) throws IOException {
|
||||||
|
// no-op
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Delete a tc filter. */
|
||||||
|
@Override
|
||||||
|
public void tcFilterDelDev(int ifIndex, boolean ingress, short prio, short proto)
|
||||||
|
throws IOException {
|
||||||
|
// no-op
|
||||||
|
return;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@@ -417,6 +449,11 @@ public class ClatCoordinatorTest {
|
|||||||
eq(XLAT_LOCAL_IPV4ADDR_STRING), eq(XLAT_LOCAL_IPV6ADDR_STRING));
|
eq(XLAT_LOCAL_IPV4ADDR_STRING), eq(XLAT_LOCAL_IPV6ADDR_STRING));
|
||||||
inOrder.verify(mEgressMap).insertEntry(eq(EGRESS_KEY), eq(EGRESS_VALUE));
|
inOrder.verify(mEgressMap).insertEntry(eq(EGRESS_KEY), eq(EGRESS_VALUE));
|
||||||
inOrder.verify(mIngressMap).insertEntry(eq(INGRESS_KEY), eq(INGRESS_VALUE));
|
inOrder.verify(mIngressMap).insertEntry(eq(INGRESS_KEY), eq(INGRESS_VALUE));
|
||||||
|
inOrder.verify(mDeps).tcQdiscAddDevClsact(eq(STACKED_IFINDEX));
|
||||||
|
inOrder.verify(mDeps).tcFilterAddDevBpf(eq(STACKED_IFINDEX), eq(EGRESS),
|
||||||
|
eq((short) PRIO_CLAT), eq((short) ETH_P_IP), eq(EGRESS_PROG_PATH));
|
||||||
|
inOrder.verify(mDeps).tcFilterAddDevBpf(eq(BASE_IFINDEX), eq(INGRESS),
|
||||||
|
eq((short) PRIO_CLAT), eq((short) ETH_P_IPV6), eq(INGRESS_PROG_PATH));
|
||||||
inOrder.verifyNoMoreInteractions();
|
inOrder.verifyNoMoreInteractions();
|
||||||
|
|
||||||
// [2] Start clatd again failed.
|
// [2] Start clatd again failed.
|
||||||
|
|||||||
Reference in New Issue
Block a user