Merge "Import translations. DO NOT MERGE ANYWHERE"
diff --git a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
index 49442a6..f8169cb 100644
--- a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
+++ b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
@@ -905,10 +905,16 @@
if (forwardingPairExists(intIface, extIface)) return;
+ boolean firstUpstreamForThisDownstream = !isAnyForwardingPairOnDownstream(intIface);
boolean firstDownstreamForThisUpstream = !isAnyForwardingPairOnUpstream(extIface);
forwardingPairAdd(intIface, extIface);
- mBpfCoordinatorShim.attachProgram(intIface, UPSTREAM);
+ // Attach if the downstream is the first time to be used in a forwarding pair.
+ // Ex: IPv6 only interface has two forwarding pair, iface and v4-iface, on the
+ // same downstream.
+ if (firstUpstreamForThisDownstream) {
+ mBpfCoordinatorShim.attachProgram(intIface, UPSTREAM);
+ }
// Attach if the upstream is the first time to be used in a forwarding pair.
if (firstDownstreamForThisUpstream) {
mBpfCoordinatorShim.attachProgram(extIface, DOWNSTREAM);
@@ -922,7 +928,9 @@
forwardingPairRemove(intIface, extIface);
// Detaching program may fail because the interface has been removed already.
- mBpfCoordinatorShim.detachProgram(intIface);
+ if (!isAnyForwardingPairOnDownstream(intIface)) {
+ mBpfCoordinatorShim.detachProgram(intIface);
+ }
// Detach if no more forwarding pair is using the upstream.
if (!isAnyForwardingPairOnUpstream(extIface)) {
mBpfCoordinatorShim.detachProgram(extIface);
@@ -1827,6 +1835,13 @@
return mForwardingPairs.containsKey(extIface);
}
+ private boolean isAnyForwardingPairOnDownstream(@NonNull String intIface) {
+ for (final HashSet downstreams : mForwardingPairs.values()) {
+ if (downstreams.contains(intIface)) return true;
+ }
+ return false;
+ }
+
@NonNull
private NetworkStats buildNetworkStats(@NonNull StatsType type, int ifIndex,
@NonNull final ForwardedStats diff) {
diff --git a/Tethering/tests/integration/Android.bp b/Tethering/tests/integration/Android.bp
index ca8d3de..9aa2cff 100644
--- a/Tethering/tests/integration/Android.bp
+++ b/Tethering/tests/integration/Android.bp
@@ -79,7 +79,6 @@
defaults: ["TetheringIntegrationTestsDefaults"],
test_suites: [
"device-tests",
- "mts-tethering",
],
compile_multilib: "both",
jarjar_rules: ":NetworkStackJarJarRules",
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 fa1d881..788673a 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
@@ -1277,47 +1277,62 @@
try {
final String intIface1 = "wlan1";
final String intIface2 = "rndis0";
- final String extIface = "rmnet_data0";
+ final String extIface1 = "rmnet_data0";
+ final String extIface2 = "v4-rmnet_data0";
final String virtualIface = "ipsec0";
final BpfUtils mockMarkerBpfUtils = staticMockMarker(BpfUtils.class);
final BpfCoordinator coordinator = makeBpfCoordinator();
// [1] Add the forwarding pair <wlan1, rmnet_data0>. Expect that attach both wlan1 and
// rmnet_data0.
- coordinator.maybeAttachProgram(intIface1, extIface);
- ExtendedMockito.verify(() -> BpfUtils.attachProgram(extIface, DOWNSTREAM));
+ coordinator.maybeAttachProgram(intIface1, extIface1);
+ ExtendedMockito.verify(() -> BpfUtils.attachProgram(extIface1, DOWNSTREAM));
ExtendedMockito.verify(() -> BpfUtils.attachProgram(intIface1, UPSTREAM));
ExtendedMockito.verifyNoMoreInteractions(mockMarkerBpfUtils);
ExtendedMockito.clearInvocations(mockMarkerBpfUtils);
// [2] Add the forwarding pair <wlan1, rmnet_data0> again. Expect no more action.
- coordinator.maybeAttachProgram(intIface1, extIface);
+ coordinator.maybeAttachProgram(intIface1, extIface1);
ExtendedMockito.verifyNoMoreInteractions(mockMarkerBpfUtils);
ExtendedMockito.clearInvocations(mockMarkerBpfUtils);
// [3] Add the forwarding pair <rndis0, rmnet_data0>. Expect that attach rndis0 only.
- coordinator.maybeAttachProgram(intIface2, extIface);
+ coordinator.maybeAttachProgram(intIface2, extIface1);
ExtendedMockito.verify(() -> BpfUtils.attachProgram(intIface2, UPSTREAM));
ExtendedMockito.verifyNoMoreInteractions(mockMarkerBpfUtils);
ExtendedMockito.clearInvocations(mockMarkerBpfUtils);
- // [4] Remove the forwarding pair <rndis0, rmnet_data0>. Expect detach rndis0 only.
- coordinator.maybeDetachProgram(intIface2, extIface);
+ // [4] Add the forwarding pair <rndis0, v4-rmnet_data0>. Expect that attach
+ // v4-rmnet_data0 only.
+ coordinator.maybeAttachProgram(intIface2, extIface2);
+ ExtendedMockito.verify(() -> BpfUtils.attachProgram(extIface2, DOWNSTREAM));
+ ExtendedMockito.verifyNoMoreInteractions(mockMarkerBpfUtils);
+ ExtendedMockito.clearInvocations(mockMarkerBpfUtils);
+
+ // [5] Remove the forwarding pair <rndis0, v4-rmnet_data0>. Expect detach
+ // v4-rmnet_data0 only.
+ coordinator.maybeDetachProgram(intIface2, extIface2);
+ ExtendedMockito.verify(() -> BpfUtils.detachProgram(extIface2));
+ ExtendedMockito.verifyNoMoreInteractions(mockMarkerBpfUtils);
+ ExtendedMockito.clearInvocations(mockMarkerBpfUtils);
+
+ // [6] Remove the forwarding pair <rndis0, rmnet_data0>. Expect detach rndis0 only.
+ coordinator.maybeDetachProgram(intIface2, extIface1);
ExtendedMockito.verify(() -> BpfUtils.detachProgram(intIface2));
ExtendedMockito.verifyNoMoreInteractions(mockMarkerBpfUtils);
ExtendedMockito.clearInvocations(mockMarkerBpfUtils);
- // [5] Remove the forwarding pair <wlan1, rmnet_data0>. Expect that detach both wlan1
+ // [7] Remove the forwarding pair <wlan1, rmnet_data0>. Expect that detach both wlan1
// and rmnet_data0.
- coordinator.maybeDetachProgram(intIface1, extIface);
- ExtendedMockito.verify(() -> BpfUtils.detachProgram(extIface));
+ coordinator.maybeDetachProgram(intIface1, extIface1);
+ ExtendedMockito.verify(() -> BpfUtils.detachProgram(extIface1));
ExtendedMockito.verify(() -> BpfUtils.detachProgram(intIface1));
ExtendedMockito.verifyNoMoreInteractions(mockMarkerBpfUtils);
ExtendedMockito.clearInvocations(mockMarkerBpfUtils);
- // [6] Skip attaching if upstream is virtual interface.
+ // [8] Skip attaching if upstream is virtual interface.
coordinator.maybeAttachProgram(intIface1, virtualIface);
- ExtendedMockito.verify(() -> BpfUtils.attachProgram(extIface, DOWNSTREAM), never());
+ ExtendedMockito.verify(() -> BpfUtils.attachProgram(extIface1, DOWNSTREAM), never());
ExtendedMockito.verify(() -> BpfUtils.attachProgram(intIface1, UPSTREAM), never());
ExtendedMockito.verifyNoMoreInteractions(mockMarkerBpfUtils);
ExtendedMockito.clearInvocations(mockMarkerBpfUtils);
diff --git a/bpf_progs/offload.c b/bpf_progs/offload.c
index 4eb1e8d..cb83b92 100644
--- a/bpf_progs/offload.c
+++ b/bpf_progs/offload.c
@@ -320,50 +320,32 @@
// ANDROID: net: bpf: permit redirect from ingress L3 to egress L2 devices at near max mtu
// (the first of those has already been upstreamed)
//
-// 5.4 kernel support was only added to Android Common Kernel in R,
-// and thus a 5.4 kernel always supports this.
+// These were added to 4.14+ Android Common Kernel in R (including the original release of ACK 5.4)
+// and there is a test in kernel/tests/net/test/bpf_test.py testSkbChangeHead()
+// and in system/netd/tests/binder_test.cpp NetdBinderTest TetherOffloadForwarding.
//
-// Hence, these mandatory (must load successfully) implementations for 5.4+ kernels:
-DEFINE_BPF_PROG_KVER("schedcls/tether_downstream6_rawip$5_4", TETHERING_UID, TETHERING_GID,
- sched_cls_tether_downstream6_rawip_5_4, KVER(5, 4, 0))
+// Hence, these mandatory (must load successfully) implementations for 4.14+ kernels:
+DEFINE_BPF_PROG_KVER("schedcls/tether_downstream6_rawip$4_14", TETHERING_UID, TETHERING_GID,
+ sched_cls_tether_downstream6_rawip_4_14, KVER(4, 14, 0))
(struct __sk_buff* skb) {
return do_forward6(skb, /* is_ethernet */ false, /* downstream */ true);
}
-DEFINE_BPF_PROG_KVER("schedcls/tether_upstream6_rawip$5_4", TETHERING_UID, TETHERING_GID,
- sched_cls_tether_upstream6_rawip_5_4, KVER(5, 4, 0))
+DEFINE_BPF_PROG_KVER("schedcls/tether_upstream6_rawip$4_14", TETHERING_UID, TETHERING_GID,
+ sched_cls_tether_upstream6_rawip_4_14, KVER(4, 14, 0))
(struct __sk_buff* skb) {
return do_forward6(skb, /* is_ethernet */ false, /* downstream */ false);
}
-// and these identical optional (may fail to load) implementations for [4.14..5.4) patched kernels:
-DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE("schedcls/tether_downstream6_rawip$4_14",
- TETHERING_UID, TETHERING_GID,
- sched_cls_tether_downstream6_rawip_4_14,
- KVER(4, 14, 0), KVER(5, 4, 0))
-(struct __sk_buff* skb) {
- return do_forward6(skb, /* is_ethernet */ false, /* downstream */ true);
-}
-
-DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE("schedcls/tether_upstream6_rawip$4_14",
- TETHERING_UID, TETHERING_GID,
- sched_cls_tether_upstream6_rawip_4_14,
- KVER(4, 14, 0), KVER(5, 4, 0))
-(struct __sk_buff* skb) {
- return do_forward6(skb, /* is_ethernet */ false, /* downstream */ false);
-}
-
-// and define no-op stubs for [4.9,4.14) and unpatched [4.14,5.4) kernels.
-// (if the above real 4.14+ program loaded successfully, then bpfloader will have already pinned
-// it at the same location this one would be pinned at and will thus skip loading this stub)
+// and define no-op stubs for pre-4.14 kernels.
DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_downstream6_rawip$stub", TETHERING_UID, TETHERING_GID,
- sched_cls_tether_downstream6_rawip_stub, KVER_NONE, KVER(5, 4, 0))
+ sched_cls_tether_downstream6_rawip_stub, KVER_NONE, KVER(4, 14, 0))
(struct __sk_buff* skb) {
return TC_ACT_PIPE;
}
DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_upstream6_rawip$stub", TETHERING_UID, TETHERING_GID,
- sched_cls_tether_upstream6_rawip_stub, KVER_NONE, KVER(5, 4, 0))
+ sched_cls_tether_upstream6_rawip_stub, KVER_NONE, KVER(4, 14, 0))
(struct __sk_buff* skb) {
return TC_ACT_PIPE;
}
diff --git a/tests/native/utilities/Android.bp b/tests/native/utilities/Android.bp
index 7668cc1..4706b3d 100644
--- a/tests/native/utilities/Android.bp
+++ b/tests/native/utilities/Android.bp
@@ -13,6 +13,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_test_library {
name: "libconnectivity_native_test_utils",
defaults: [