diff --git a/common/Android.bp b/common/Android.bp index 95d84cc879..acd2349bc9 100644 --- a/common/Android.bp +++ b/common/Android.bp @@ -39,6 +39,11 @@ java_aconfig_library { ], } +// This library MUST NOT be available to platform. This is because if the +// platform depends on a flag, it will not be able to delete that flag until +// that platform version is no longer supported by mainline. Additionally, +// there is no any safety mechanism that prevents the module from +// deleting the flag by mistake, regressing on previous platform versions. java_aconfig_library { name: "com.android.net.flags-aconfig-java-export", aconfig_declarations: "com.android.net.flags-aconfig", diff --git a/common/flags.aconfig b/common/flags.aconfig index 17ddff8dc3..9fcd981be9 100644 --- a/common/flags.aconfig +++ b/common/flags.aconfig @@ -191,3 +191,11 @@ flag { bug: "397536853" is_fixed_read_only: true } + +flag { + name: "qos_filter_ip_range_matching" + namespace: "android_core_networking" + description: "Flag for API to provide IP address range based QoS socket matching." + bug: "406146808" + is_fixed_read_only: true +} diff --git a/framework/api/system-current.txt b/framework/api/system-current.txt index bef29a4283..e631e5d9a4 100644 --- a/framework/api/system-current.txt +++ b/framework/api/system-current.txt @@ -433,8 +433,10 @@ package android.net { public abstract class QosFilter { method @NonNull public abstract android.net.Network getNetwork(); method public abstract boolean matchesLocalAddress(@NonNull java.net.InetAddress, int, int); + method @FlaggedApi("com.android.net.flags.qos_filter_ip_range_matching") public abstract boolean matchesLocalPrefix(@NonNull android.net.IpPrefix, int, int); method public boolean matchesProtocol(int); method public abstract boolean matchesRemoteAddress(@NonNull java.net.InetAddress, int, int); + method @FlaggedApi("com.android.net.flags.qos_filter_ip_range_matching") public abstract boolean matchesRemotePrefix(@NonNull android.net.IpPrefix, int, int); } public final class QosSession implements android.os.Parcelable { diff --git a/framework/src/android/net/QosFilter.java b/framework/src/android/net/QosFilter.java index a731b23c10..c28671085f 100644 --- a/framework/src/android/net/QosFilter.java +++ b/framework/src/android/net/QosFilter.java @@ -16,9 +16,12 @@ package android.net; +import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.SystemApi; +import com.android.net.flags.Flags; + import java.net.InetAddress; /** @@ -93,6 +96,38 @@ public abstract class QosFilter { public abstract boolean matchesRemoteAddress(@NonNull InetAddress address, int startPort, int endPort); + /** + * Determines whether or not the parameters will be matched with prefix length, source address + * and port. + * + * @param ipPrefix the UE side IP address and prefix length included in IP packet filter set of + * a QoS flow assigned on {@link Network}. + * @param startPort the start of UE side port range included in IP packet filter set of a QoS + * flow assigned on {@link Network}. + * @param endPort the end of UE side port range included in IP packet filter set of a QoS flow + * assigned on {@link Network}. + * @return whether the parameters match the UE side address and port of the filter + */ + @FlaggedApi(Flags.FLAG_QOS_FILTER_IP_RANGE_MATCHING) + public abstract boolean matchesLocalPrefix( + @NonNull IpPrefix ipPrefix, int startPort, int endPort); + + /** + * Determines whether or not the parameters will be matched with prefix length, remote address + * and port. + * + * @param ipPrefix the remote IP address and prefix length included in IP packet filter set of a + * QoS flow assigned on {@link Network}. + * @param startPort the start of remote port range included in IP packet filter set of a QoS + * flow assigned on {@link Network}. + * @param endPort the end of the remote range included in IP packet filter set of a QoS flow + * assigned on {@link Network}. + * @return whether the parameters match the remote address and port of the filter + */ + @FlaggedApi(Flags.FLAG_QOS_FILTER_IP_RANGE_MATCHING) + public abstract boolean matchesRemotePrefix( + @NonNull IpPrefix ipPrefix, int startPort, int endPort); + /** * Determines whether or not the parameter will be matched with this filter. * diff --git a/framework/src/android/net/QosSocketFilter.java b/framework/src/android/net/QosSocketFilter.java index 5ceeb67127..ecc2af1446 100644 --- a/framework/src/android/net/QosSocketFilter.java +++ b/framework/src/android/net/QosSocketFilter.java @@ -36,6 +36,7 @@ import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import java.io.FileDescriptor; +import java.net.Inet4Address; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; @@ -179,10 +180,11 @@ public class QosSocketFilter extends QosFilter { @Override public boolean matchesLocalAddress(@NonNull final InetAddress address, final int startPort, final int endPort) { - if (mQosSocketInfo.getLocalSocketAddress() == null) { - return false; - } - return matchesAddress(mQosSocketInfo.getLocalSocketAddress(), address, startPort, + return matchesLocalPrefix( + address instanceof Inet4Address + ? new IpPrefix(address, 32) + : new IpPrefix(address, 128), + startPort, endPort); } @@ -192,11 +194,33 @@ public class QosSocketFilter extends QosFilter { @Override public boolean matchesRemoteAddress(@NonNull final InetAddress address, final int startPort, final int endPort) { + return matchesRemotePrefix( + address instanceof Inet4Address + ? new IpPrefix(address, 32) + : new IpPrefix(address, 128), + startPort, + endPort); + } + + /** {@inheritDoc} */ + @Override + public boolean matchesLocalPrefix( + @NonNull final IpPrefix ipPrefix, final int startPort, final int endPort) { + if (mQosSocketInfo.getLocalSocketAddress() == null) { + return false; + } + return matchesAddress(mQosSocketInfo.getLocalSocketAddress(), ipPrefix, startPort, endPort); + } + + /** {@inheritDoc} */ + @Override + public boolean matchesRemotePrefix( + @NonNull final IpPrefix ipPrefix, final int startPort, final int endPort) { if (mQosSocketInfo.getRemoteSocketAddress() == null) { return false; } - return matchesAddress(mQosSocketInfo.getRemoteSocketAddress(), address, startPort, - endPort); + return matchesAddress( + mQosSocketInfo.getRemoteSocketAddress(), ipPrefix, startPort, endPort); } /** @@ -212,25 +236,27 @@ public class QosSocketFilter extends QosFilter { } /** - * Called from {@link QosSocketFilter#matchesLocalAddress(InetAddress, int, int)} - * and {@link QosSocketFilter#matchesRemoteAddress(InetAddress, int, int)} with the - * filterSocketAddress coming from {@link QosSocketInfo#getLocalSocketAddress()}. - *
- * This method exists for testing purposes since {@link QosSocketInfo} couldn't be mocked - * due to being final. + * Called from {@link QosSocketFilter#matchesLocalPrefix(IpPrefix, int, int)} and {@link + * QosSocketFilter#matchesRemotePrefix(IpPrefix, int, int)} with the filterSocketAddress coming + * from {@link QosSocketInfo#getLocalSocketAddress()}. + * + *
This method exists for testing purposes since {@link QosSocketInfo} couldn't be mocked due
+ * to being final.
*
* @param filterSocketAddress the socket address of the filter
- * @param address the address to compare the filterSocketAddressWith
+ * @param ipPrefix the IP address with prefix length to compare the filterSocketAddressWith
* @param startPort the start of the port range to check
* @param endPort the end of the port range to check
*/
@VisibleForTesting
- public static boolean matchesAddress(@NonNull final InetSocketAddress filterSocketAddress,
- @NonNull final InetAddress address,
- final int startPort, final int endPort) {
+ public static boolean matchesAddress(
+ @NonNull final InetSocketAddress filterSocketAddress,
+ @NonNull final IpPrefix ipPrefix,
+ final int startPort,
+ final int endPort) {
return startPort <= filterSocketAddress.getPort()
&& endPort >= filterSocketAddress.getPort()
- && (address.isAnyLocalAddress()
- || filterSocketAddress.getAddress().equals(address));
+ && (ipPrefix.getAddress().isAnyLocalAddress()
+ || ipPrefix.contains(filterSocketAddress.getAddress()));
}
}
diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
index 8592ae41da..8a541ed270 100644
--- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
+++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
@@ -1392,6 +1392,22 @@ class NetworkAgentTest {
agent.expectCallback