From 01f2550ac48997f3ab60017971f62ddf439a3c72 Mon Sep 17 00:00:00 2001 From: Hungming Chen Date: Tue, 28 Jun 2022 22:47:00 +0800 Subject: [PATCH] Move struct {Clat*, Tether4*, TetherStats*} to connectivity module Needed because these struct classes should not be exposed. Only used for the connectivity module and its tests. Bug: 234160319 Test: atest ConnectivityCoverageTests The moved files are identical. diff packages/modules/Connectivity/common/src/com/android/net/module/util/bpf/ClatEgress4Key.java frameworks/libs/net/common/device/com/android/net/module/util/bpf/ClatEgress4Key.java diff packages/modules/Connectivity/common/src/com/android/net/module/util/bpf/ClatEgress4Value.java frameworks/libs/net/common/device/com/android/net/module/util/bpf/ClatEgress4Value.java diff packages/modules/Connectivity/common/src/com/android/net/module/util/bpf/ClatIngress6Key.java frameworks/libs/net/common/device/com/android/net/module/util/bpf/ClatIngress6Key.java diff packages/modules/Connectivity/common/src/com/android/net/module/util/bpf/ClatIngress6Value.java frameworks/libs/net/common/device/com/android/net/module/util/bpf/ClatIngress6Value.java diff packages/modules/Connectivity/common/src/com/android/net/module/util/bpf/Tether4Key.java frameworks/libs/net/common/device/com/android/net/module/util/bpf/Tether4Key.java diff packages/modules/Connectivity/common/src/com/android/net/module/util/bpf/Tether4Value.java frameworks/libs/net/common/device/com/android/net/module/util/bpf/Tether4Value.java diff packages/modules/Connectivity/common/src/com/android/net/module/util/bpf/TetherStatsKey.java frameworks/libs/net/common/device/com/android/net/module/util/bpf/TetherStatsKey.java diff packages/modules/Connectivity/common/src/com/android/net/module/util/bpf/TetherStatsValue.java frameworks/libs/net/common/device/com/android/net/module/util/bpf/TetherStatsValue.java diff packages/modules/Connectivity/common/src/com/android/net/module/util/bpf/ClatEgress4Key.java frameworks/libs/net/common/device/com/android/net/module/util/bpf/ClatEgress4Key.java (no diff) Change-Id: I4ce8045150bdbf04c63c5262c58a0ebcc30d395c --- Tethering/Android.bp | 1 + Tethering/tests/integration/Android.bp | 1 + common/Android.bp | 45 +++++++++ .../net/module/util/bpf/ClatEgress4Key.java | 37 +++++++ .../net/module/util/bpf/ClatEgress4Value.java | 46 +++++++++ .../net/module/util/bpf/ClatIngress6Key.java | 41 ++++++++ .../module/util/bpf/ClatIngress6Value.java | 37 +++++++ .../net/module/util/bpf/Tether4Key.java | 81 ++++++++++++++++ .../net/module/util/bpf/Tether4Value.java | 97 +++++++++++++++++++ .../net/module/util/bpf/TetherStatsKey.java | 53 ++++++++++ .../net/module/util/bpf/TetherStatsValue.java | 80 +++++++++++++++ service/Android.bp | 1 + 12 files changed, 520 insertions(+) create mode 100644 common/Android.bp create mode 100644 common/src/com/android/net/module/util/bpf/ClatEgress4Key.java create mode 100644 common/src/com/android/net/module/util/bpf/ClatEgress4Value.java create mode 100644 common/src/com/android/net/module/util/bpf/ClatIngress6Key.java create mode 100644 common/src/com/android/net/module/util/bpf/ClatIngress6Value.java create mode 100644 common/src/com/android/net/module/util/bpf/Tether4Key.java create mode 100644 common/src/com/android/net/module/util/bpf/Tether4Value.java create mode 100644 common/src/com/android/net/module/util/bpf/TetherStatsKey.java create mode 100644 common/src/com/android/net/module/util/bpf/TetherStatsValue.java diff --git a/Tethering/Android.bp b/Tethering/Android.bp index 28edc8a40f..bfba5cdfc5 100644 --- a/Tethering/Android.bp +++ b/Tethering/Android.bp @@ -37,6 +37,7 @@ java_defaults { ], static_libs: [ "androidx.annotation_annotation", + "connectivity-net-module-utils-bpf", "modules-utils-build", "modules-utils-statemachine", "networkstack-client", diff --git a/Tethering/tests/integration/Android.bp b/Tethering/tests/integration/Android.bp index 31c3df3dd9..ca8d3de099 100644 --- a/Tethering/tests/integration/Android.bp +++ b/Tethering/tests/integration/Android.bp @@ -32,6 +32,7 @@ java_defaults { "net-tests-utils", "net-utils-device-common-bpf", "testables", + "connectivity-net-module-utils-bpf", ], libs: [ "android.test.runner", diff --git a/common/Android.bp b/common/Android.bp new file mode 100644 index 0000000000..729ef3250f --- /dev/null +++ b/common/Android.bp @@ -0,0 +1,45 @@ +// +// 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 { + // See: http://go/android-license-faq + default_applicable_licenses: ["Android-Apache-2.0"], +} + +java_library { + name: "connectivity-net-module-utils-bpf", + srcs: [ + "src/com/android/net/module/util/bpf/*.java", + ], + sdk_version: "module_current", + min_sdk_version: "29", + visibility: [ + // Do not add any lib. This library is only shared inside connectivity module + // and its tests. + "//packages/modules/Connectivity:__subpackages__", + ], + libs: [ + "androidx.annotation_annotation", + "framework-connectivity.stubs.module_lib", + ], + static_libs: [ + "net-utils-device-common-struct", + ], + apex_available: [ + "com.android.tethering", + ], + lint: { strict_updatability_linting: true }, +} diff --git a/common/src/com/android/net/module/util/bpf/ClatEgress4Key.java b/common/src/com/android/net/module/util/bpf/ClatEgress4Key.java new file mode 100644 index 0000000000..12200ec60f --- /dev/null +++ b/common/src/com/android/net/module/util/bpf/ClatEgress4Key.java @@ -0,0 +1,37 @@ +/* + * 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 com.android.net.module.util.bpf; + +import com.android.net.module.util.Struct; +import com.android.net.module.util.Struct.Field; +import com.android.net.module.util.Struct.Type; + +import java.net.Inet4Address; + +/** Key type for clat egress IPv4 maps. */ +public class ClatEgress4Key extends Struct { + @Field(order = 0, type = Type.U32) + public final long iif; // The input interface index + + @Field(order = 1, type = Type.Ipv4Address) + public final Inet4Address local4; // The source IPv4 address + + public ClatEgress4Key(final long iif, final Inet4Address local4) { + this.iif = iif; + this.local4 = local4; + } +} diff --git a/common/src/com/android/net/module/util/bpf/ClatEgress4Value.java b/common/src/com/android/net/module/util/bpf/ClatEgress4Value.java new file mode 100644 index 0000000000..c10cb4da32 --- /dev/null +++ b/common/src/com/android/net/module/util/bpf/ClatEgress4Value.java @@ -0,0 +1,46 @@ +/* + * 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 com.android.net.module.util.bpf; + +import com.android.net.module.util.Struct; +import com.android.net.module.util.Struct.Field; +import com.android.net.module.util.Struct.Type; + +import java.net.Inet6Address; + +/** Value type for clat egress IPv4 maps. */ +public class ClatEgress4Value extends Struct { + @Field(order = 0, type = Type.U32) + public final long oif; // The output interface to redirect to + + @Field(order = 1, type = Type.Ipv6Address) + public final Inet6Address local6; // The full 128-bits of the source IPv6 address + + @Field(order = 2, type = Type.Ipv6Address) + public final Inet6Address pfx96; // The destination /96 nat64 prefix, bottom 32 bits must be 0 + + @Field(order = 3, type = Type.U8, padding = 3) + public final short oifIsEthernet; // Whether the output interface requires ethernet header + + public ClatEgress4Value(final long oif, final Inet6Address local6, final Inet6Address pfx96, + final short oifIsEthernet) { + this.oif = oif; + this.local6 = local6; + this.pfx96 = pfx96; + this.oifIsEthernet = oifIsEthernet; + } +} diff --git a/common/src/com/android/net/module/util/bpf/ClatIngress6Key.java b/common/src/com/android/net/module/util/bpf/ClatIngress6Key.java new file mode 100644 index 0000000000..1e2f4e06d6 --- /dev/null +++ b/common/src/com/android/net/module/util/bpf/ClatIngress6Key.java @@ -0,0 +1,41 @@ +/* + * 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 com.android.net.module.util.bpf; + +import com.android.net.module.util.Struct; +import com.android.net.module.util.Struct.Field; +import com.android.net.module.util.Struct.Type; + +import java.net.Inet6Address; + +/** Key type for clat ingress IPv6 maps. */ +public class ClatIngress6Key extends Struct { + @Field(order = 0, type = Type.U32) + public final long iif; // The input interface index + + @Field(order = 1, type = Type.Ipv6Address) + public final Inet6Address pfx96; // The source /96 nat64 prefix, bottom 32 bits must be 0 + + @Field(order = 2, type = Type.Ipv6Address) + public final Inet6Address local6; // The full 128-bits of the destination IPv6 address + + public ClatIngress6Key(final long iif, final Inet6Address pfx96, final Inet6Address local6) { + this.iif = iif; + this.pfx96 = pfx96; + this.local6 = local6; + } +} diff --git a/common/src/com/android/net/module/util/bpf/ClatIngress6Value.java b/common/src/com/android/net/module/util/bpf/ClatIngress6Value.java new file mode 100644 index 0000000000..bfec44fac2 --- /dev/null +++ b/common/src/com/android/net/module/util/bpf/ClatIngress6Value.java @@ -0,0 +1,37 @@ +/* + * 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 com.android.net.module.util.bpf; + +import com.android.net.module.util.Struct; +import com.android.net.module.util.Struct.Field; +import com.android.net.module.util.Struct.Type; + +import java.net.Inet4Address; + +/** Value type for clat ingress IPv6 maps. */ +public class ClatIngress6Value extends Struct { + @Field(order = 0, type = Type.U32) + public final long oif; // The output interface to redirect to (0 means don't redirect) + + @Field(order = 1, type = Type.Ipv4Address) + public final Inet4Address local4; // The destination IPv4 address + + public ClatIngress6Value(final long oif, final Inet4Address local4) { + this.oif = oif; + this.local4 = local4; + } +} diff --git a/common/src/com/android/net/module/util/bpf/Tether4Key.java b/common/src/com/android/net/module/util/bpf/Tether4Key.java new file mode 100644 index 0000000000..638576f026 --- /dev/null +++ b/common/src/com/android/net/module/util/bpf/Tether4Key.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2020 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 com.android.net.module.util.bpf; + +import android.net.MacAddress; + +import androidx.annotation.NonNull; + +import com.android.net.module.util.Struct; +import com.android.net.module.util.Struct.Field; +import com.android.net.module.util.Struct.Type; + +import java.net.Inet4Address; +import java.net.UnknownHostException; +import java.util.Objects; + +/** 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 = 1, type = Type.EUI48) + public final MacAddress dstMac; + + @Field(order = 2, type = Type.U8, padding = 1) + public final short l4proto; + + @Field(order = 3, type = Type.ByteArray, arraysize = 4) + public final byte[] src4; + + @Field(order = 4, type = Type.ByteArray, arraysize = 4) + public final byte[] dst4; + + @Field(order = 5, type = Type.UBE16) + public final int srcPort; + + @Field(order = 6, type = Type.UBE16) + public final int dstPort; + + public Tether4Key(final long iif, @NonNull final MacAddress dstMac, final short l4proto, + final byte[] src4, final byte[] dst4, final int srcPort, + final int dstPort) { + Objects.requireNonNull(dstMac); + + this.iif = iif; + this.dstMac = dstMac; + this.l4proto = l4proto; + this.src4 = src4; + this.dst4 = dst4; + this.srcPort = srcPort; + this.dstPort = dstPort; + } + + @Override + public String toString() { + try { + return String.format( + "iif: %d, dstMac: %s, l4proto: %d, src4: %s, dst4: %s, " + + "srcPort: %d, dstPort: %d", + iif, dstMac, l4proto, + Inet4Address.getByAddress(src4), Inet4Address.getByAddress(dst4), + Short.toUnsignedInt((short) srcPort), Short.toUnsignedInt((short) dstPort)); + } catch (UnknownHostException | IllegalArgumentException e) { + return String.format("Invalid IP address", e); + } + } +} diff --git a/common/src/com/android/net/module/util/bpf/Tether4Value.java b/common/src/com/android/net/module/util/bpf/Tether4Value.java new file mode 100644 index 0000000000..de98766ee3 --- /dev/null +++ b/common/src/com/android/net/module/util/bpf/Tether4Value.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2020 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 com.android.net.module.util.bpf; + +import android.net.MacAddress; + +import androidx.annotation.NonNull; + +import com.android.net.module.util.Struct; +import com.android.net.module.util.Struct.Field; +import com.android.net.module.util.Struct.Type; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Objects; + +/** Value type for downstream & upstream IPv4 forwarding maps. */ +public class Tether4Value extends Struct { + @Field(order = 0, type = Type.U32) + public final long oif; + + // The ethhdr struct which is defined in uapi/linux/if_ether.h + @Field(order = 1, type = Type.EUI48) + public final MacAddress ethDstMac; + @Field(order = 2, type = Type.EUI48) + public final MacAddress ethSrcMac; + @Field(order = 3, type = Type.UBE16) + public final int ethProto; // Packet type ID field. + + @Field(order = 4, type = Type.U16) + public final int pmtu; + + @Field(order = 5, type = Type.ByteArray, arraysize = 16) + public final byte[] src46; + + @Field(order = 6, type = Type.ByteArray, arraysize = 16) + public final byte[] dst46; + + @Field(order = 7, type = Type.UBE16) + public final int srcPort; + + @Field(order = 8, type = Type.UBE16) + public final int dstPort; + + // TODO: consider using U64. + @Field(order = 9, type = Type.U63) + public final long lastUsed; + + public Tether4Value(final long 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) { + Objects.requireNonNull(ethDstMac); + Objects.requireNonNull(ethSrcMac); + + this.oif = oif; + this.ethDstMac = ethDstMac; + this.ethSrcMac = ethSrcMac; + this.ethProto = ethProto; + this.pmtu = pmtu; + this.src46 = src46; + this.dst46 = dst46; + this.srcPort = srcPort; + this.dstPort = dstPort; + this.lastUsed = lastUsed; + } + + @Override + public String toString() { + try { + return String.format( + "oif: %d, ethDstMac: %s, ethSrcMac: %s, ethProto: %d, pmtu: %d, " + + "src46: %s, dst46: %s, srcPort: %d, dstPort: %d, " + + "lastUsed: %d", + oif, ethDstMac, ethSrcMac, ethProto, pmtu, + InetAddress.getByAddress(src46), InetAddress.getByAddress(dst46), + Short.toUnsignedInt((short) srcPort), Short.toUnsignedInt((short) dstPort), + lastUsed); + } catch (UnknownHostException | IllegalArgumentException e) { + return String.format("Invalid IP address", e); + } + } +} diff --git a/common/src/com/android/net/module/util/bpf/TetherStatsKey.java b/common/src/com/android/net/module/util/bpf/TetherStatsKey.java new file mode 100644 index 0000000000..c6d595be64 --- /dev/null +++ b/common/src/com/android/net/module/util/bpf/TetherStatsKey.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2020 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 com.android.net.module.util.bpf; + +import com.android.net.module.util.Struct; +import com.android.net.module.util.Struct.Field; +import com.android.net.module.util.Struct.Type; + +/** The key of BpfMap which is used for tethering stats. */ +public class TetherStatsKey extends Struct { + @Field(order = 0, type = Type.U32) + public final long ifindex; // upstream interface index + + public TetherStatsKey(final long ifindex) { + this.ifindex = ifindex; + } + + // TODO: remove equals, hashCode and toString once aosp/1536721 is merged. + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + + if (!(obj instanceof TetherStatsKey)) return false; + + final TetherStatsKey that = (TetherStatsKey) obj; + + return ifindex == that.ifindex; + } + + @Override + public int hashCode() { + return Long.hashCode(ifindex); + } + + @Override + public String toString() { + return String.format("ifindex: %d", ifindex); + } +} diff --git a/common/src/com/android/net/module/util/bpf/TetherStatsValue.java b/common/src/com/android/net/module/util/bpf/TetherStatsValue.java new file mode 100644 index 0000000000..028d217a93 --- /dev/null +++ b/common/src/com/android/net/module/util/bpf/TetherStatsValue.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2020 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 com.android.net.module.util.bpf; + +import com.android.net.module.util.Struct; +import com.android.net.module.util.Struct.Field; +import com.android.net.module.util.Struct.Type; + +/** The key of BpfMap which is used for tethering stats. */ +public class TetherStatsValue extends Struct { + // Use the signed long variable to store the uint64 stats from stats BPF map. + // U63 is enough for each data element even at 5Gbps for ~468 years. + // 2^63 / (5 * 1000 * 1000 * 1000) * 8 / 86400 / 365 = 468. + @Field(order = 0, type = Type.U63) + public final long rxPackets; + @Field(order = 1, type = Type.U63) + public final long rxBytes; + @Field(order = 2, type = Type.U63) + public final long rxErrors; + @Field(order = 3, type = Type.U63) + public final long txPackets; + @Field(order = 4, type = Type.U63) + public final long txBytes; + @Field(order = 5, type = Type.U63) + public final long txErrors; + + public TetherStatsValue(final long rxPackets, final long rxBytes, final long rxErrors, + final long txPackets, final long txBytes, final long txErrors) { + this.rxPackets = rxPackets; + this.rxBytes = rxBytes; + this.rxErrors = rxErrors; + this.txPackets = txPackets; + this.txBytes = txBytes; + this.txErrors = txErrors; + } + + // TODO: remove equals, hashCode and toString once aosp/1536721 is merged. + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + + if (!(obj instanceof TetherStatsValue)) return false; + + final TetherStatsValue that = (TetherStatsValue) obj; + + return rxPackets == that.rxPackets + && rxBytes == that.rxBytes + && rxErrors == that.rxErrors + && txPackets == that.txPackets + && txBytes == that.txBytes + && txErrors == that.txErrors; + } + + @Override + public int hashCode() { + return Long.hashCode(rxPackets) ^ Long.hashCode(rxBytes) ^ Long.hashCode(rxErrors) + ^ Long.hashCode(txPackets) ^ Long.hashCode(txBytes) ^ Long.hashCode(txErrors); + } + + @Override + public String toString() { + return String.format("rxPackets: %s, rxBytes: %s, rxErrors: %s, txPackets: %s, " + + "txBytes: %s, txErrors: %s", rxPackets, rxBytes, rxErrors, txPackets, + txBytes, txErrors); + } +} diff --git a/service/Android.bp b/service/Android.bp index c2dbce1513..7a4fb33f4a 100644 --- a/service/Android.bp +++ b/service/Android.bp @@ -158,6 +158,7 @@ java_library { static_libs: [ // Do not add libs here if they are already included // in framework-connectivity + "connectivity-net-module-utils-bpf", "connectivity_native_aidl_interface-lateststable-java", "dnsresolver_aidl_interface-V9-java", "modules-utils-shell-command-handler",