Add API for VCN configuration of UDP port 4500 NAT Timeouts

This patch adds an API to allow VCN providers to configure the UDP port
4500 hint to improve the power implications of a VPN over the VCN.

Bug: 259000745
Test: atest FrameworksVcnTests
Change-Id: Id464ab43fa15d5f6a693f73932d95d9822320acb
This commit is contained in:
Benedict Wong
2023-02-15 06:38:46 +00:00
parent 1d2bead412
commit 9ba9e079b7
8 changed files with 163 additions and 16 deletions

View File

@@ -27335,6 +27335,7 @@ package android.net.vcn {
method @NonNull public int[] getExposedCapabilities();
method @NonNull public String getGatewayConnectionName();
method @IntRange(from=0x500) public int getMaxMtu();
method public int getMinUdpPort4500NatTimeoutSeconds();
method @NonNull public long[] getRetryIntervalsMillis();
method @NonNull public java.util.List<android.net.vcn.VcnUnderlyingNetworkTemplate> getVcnUnderlyingNetworkPriorities();
method public boolean hasGatewayOption(int);
@@ -27349,6 +27350,7 @@ package android.net.vcn {
method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder removeExposedCapability(int);
method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder removeGatewayOption(int);
method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setMaxMtu(@IntRange(from=0x500) int);
method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setMinUdpPort4500NatTimeoutSeconds(@IntRange(from=0x78) int);
method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setRetryIntervalsMillis(@NonNull long[]);
method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setVcnUnderlyingNetworkPriorities(@NonNull java.util.List<android.net.vcn.VcnUnderlyingNetworkTemplate>);
}

View File

@@ -81,6 +81,12 @@ import java.util.concurrent.TimeUnit;
* </ul>
*/
public final class VcnGatewayConnectionConfig {
/** @hide */
public static final int MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET = -1;
/** @hide */
public static final int MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS = 120;
// TODO: Use MIN_MTU_V6 once it is public, @hide
@VisibleForTesting(visibility = Visibility.PRIVATE)
static final int MIN_MTU_V6 = 1280;
@@ -225,6 +231,10 @@ public final class VcnGatewayConnectionConfig {
private static final String RETRY_INTERVAL_MS_KEY = "mRetryIntervalsMs";
@NonNull private final long[] mRetryIntervalsMs;
private static final String MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS_KEY =
"mMinUdpPort4500NatTimeoutSeconds";
private final int mMinUdpPort4500NatTimeoutSeconds;
private static final String GATEWAY_OPTIONS_KEY = "mGatewayOptions";
@NonNull private final Set<Integer> mGatewayOptions;
@@ -236,12 +246,14 @@ public final class VcnGatewayConnectionConfig {
@NonNull List<VcnUnderlyingNetworkTemplate> underlyingNetworkTemplates,
@NonNull long[] retryIntervalsMs,
@IntRange(from = MIN_MTU_V6) int maxMtu,
@NonNull int minUdpPort4500NatTimeoutSeconds,
@NonNull Set<Integer> gatewayOptions) {
mGatewayConnectionName = gatewayConnectionName;
mTunnelConnectionParams = tunnelConnectionParams;
mExposedCapabilities = new TreeSet(exposedCapabilities);
mRetryIntervalsMs = retryIntervalsMs;
mMaxMtu = maxMtu;
mMinUdpPort4500NatTimeoutSeconds = minUdpPort4500NatTimeoutSeconds;
mGatewayOptions = Collections.unmodifiableSet(new ArraySet(gatewayOptions));
mUnderlyingNetworkTemplates = new ArrayList<>(underlyingNetworkTemplates);
@@ -301,6 +313,10 @@ public final class VcnGatewayConnectionConfig {
mRetryIntervalsMs = in.getLongArray(RETRY_INTERVAL_MS_KEY);
mMaxMtu = in.getInt(MAX_MTU_KEY);
mMinUdpPort4500NatTimeoutSeconds =
in.getInt(
MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS_KEY,
MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET);
validate();
}
@@ -323,6 +339,12 @@ public final class VcnGatewayConnectionConfig {
Preconditions.checkArgument(
mMaxMtu >= MIN_MTU_V6, "maxMtu must be at least IPv6 min MTU (1280)");
Preconditions.checkArgument(
mMinUdpPort4500NatTimeoutSeconds == MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET
|| mMinUdpPort4500NatTimeoutSeconds
>= MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS,
"minUdpPort4500NatTimeoutSeconds must be at least 120s");
for (int option : mGatewayOptions) {
validateGatewayOption(option);
}
@@ -451,6 +473,15 @@ public final class VcnGatewayConnectionConfig {
return mMaxMtu;
}
/**
* Retrieves the maximum supported IKEv2/IPsec NATT keepalive timeout.
*
* @see Builder#setMinUdpPort4500NatTimeoutSeconds(int)
*/
public int getMinUdpPort4500NatTimeoutSeconds() {
return mMinUdpPort4500NatTimeoutSeconds;
}
/**
* Checks if the given VCN gateway option is enabled.
*
@@ -496,6 +527,7 @@ public final class VcnGatewayConnectionConfig {
result.putPersistableBundle(GATEWAY_OPTIONS_KEY, gatewayOptionsBundle);
result.putLongArray(RETRY_INTERVAL_MS_KEY, mRetryIntervalsMs);
result.putInt(MAX_MTU_KEY, mMaxMtu);
result.putInt(MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS_KEY, mMinUdpPort4500NatTimeoutSeconds);
return result;
}
@@ -509,6 +541,7 @@ public final class VcnGatewayConnectionConfig {
mUnderlyingNetworkTemplates,
Arrays.hashCode(mRetryIntervalsMs),
mMaxMtu,
mMinUdpPort4500NatTimeoutSeconds,
mGatewayOptions);
}
@@ -525,6 +558,7 @@ public final class VcnGatewayConnectionConfig {
&& mUnderlyingNetworkTemplates.equals(rhs.mUnderlyingNetworkTemplates)
&& Arrays.equals(mRetryIntervalsMs, rhs.mRetryIntervalsMs)
&& mMaxMtu == rhs.mMaxMtu
&& mMinUdpPort4500NatTimeoutSeconds == rhs.mMinUdpPort4500NatTimeoutSeconds
&& mGatewayOptions.equals(rhs.mGatewayOptions);
}
@@ -542,6 +576,7 @@ public final class VcnGatewayConnectionConfig {
@NonNull private long[] mRetryIntervalsMs = DEFAULT_RETRY_INTERVALS_MS;
private int mMaxMtu = DEFAULT_MAX_MTU;
private int mMinUdpPort4500NatTimeoutSeconds = MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET;
@NonNull private final Set<Integer> mGatewayOptions = new ArraySet<>();
@@ -702,6 +737,29 @@ public final class VcnGatewayConnectionConfig {
return this;
}
/**
* Sets the maximum supported IKEv2/IPsec NATT keepalive timeout.
*
* <p>This is used as a power-optimization hint for other IKEv2/IPsec use cases (e.g. VPNs,
* or IWLAN) to reduce the necessary keepalive frequency, thus conserving power and data.
*
* @param minUdpPort4500NatTimeoutSeconds the maximum keepalive timeout supported by the VCN
* Gateway Connection, generally the minimum duration a NAT mapping is cached on the VCN
* Gateway.
* @return this {@link Builder} instance, for chaining
*/
@NonNull
public Builder setMinUdpPort4500NatTimeoutSeconds(
@IntRange(from = MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS)
int minUdpPort4500NatTimeoutSeconds) {
Preconditions.checkArgument(
minUdpPort4500NatTimeoutSeconds >= MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS,
"Timeout must be at least 120s");
mMinUdpPort4500NatTimeoutSeconds = minUdpPort4500NatTimeoutSeconds;
return this;
}
/**
* Enables the specified VCN gateway option.
*
@@ -744,6 +802,7 @@ public final class VcnGatewayConnectionConfig {
mUnderlyingNetworkTemplates,
mRetryIntervalsMs,
mMaxMtu,
mMinUdpPort4500NatTimeoutSeconds,
mGatewayOptions);
}
}

View File

@@ -17,6 +17,7 @@
package android.net.vcn;
import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
import static android.net.vcn.VcnGatewayConnectionConfig.MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
import android.annotation.NonNull;
@@ -49,18 +50,29 @@ import java.util.Objects;
public class VcnTransportInfo implements TransportInfo, Parcelable {
@Nullable private final WifiInfo mWifiInfo;
private final int mSubId;
private final int mMinUdpPort4500NatTimeoutSeconds;
public VcnTransportInfo(@NonNull WifiInfo wifiInfo) {
this(wifiInfo, INVALID_SUBSCRIPTION_ID);
this(wifiInfo, INVALID_SUBSCRIPTION_ID, MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET);
}
public VcnTransportInfo(@NonNull WifiInfo wifiInfo, int minUdpPort4500NatTimeoutSeconds) {
this(wifiInfo, INVALID_SUBSCRIPTION_ID, minUdpPort4500NatTimeoutSeconds);
}
public VcnTransportInfo(int subId) {
this(null /* wifiInfo */, subId);
this(null /* wifiInfo */, subId, MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET);
}
private VcnTransportInfo(@Nullable WifiInfo wifiInfo, int subId) {
public VcnTransportInfo(int subId, int minUdpPort4500NatTimeoutSeconds) {
this(null /* wifiInfo */, subId, minUdpPort4500NatTimeoutSeconds);
}
private VcnTransportInfo(
@Nullable WifiInfo wifiInfo, int subId, int minUdpPort4500NatTimeoutSeconds) {
mWifiInfo = wifiInfo;
mSubId = subId;
mMinUdpPort4500NatTimeoutSeconds = minUdpPort4500NatTimeoutSeconds;
}
/**
@@ -88,16 +100,28 @@ public class VcnTransportInfo implements TransportInfo, Parcelable {
return mSubId;
}
/**
* Get the VCN provided UDP port 4500 NAT timeout
*
* @return the UDP 4500 NAT timeout, or
* VcnGatewayConnectionConfig.MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET if not set.
*/
public int getMinUdpPort4500NatTimeoutSeconds() {
return mMinUdpPort4500NatTimeoutSeconds;
}
@Override
public int hashCode() {
return Objects.hash(mWifiInfo, mSubId);
return Objects.hash(mWifiInfo, mSubId, mMinUdpPort4500NatTimeoutSeconds);
}
@Override
public boolean equals(Object o) {
if (!(o instanceof VcnTransportInfo)) return false;
final VcnTransportInfo that = (VcnTransportInfo) o;
return Objects.equals(mWifiInfo, that.mWifiInfo) && mSubId == that.mSubId;
return Objects.equals(mWifiInfo, that.mWifiInfo)
&& mSubId == that.mSubId
&& mMinUdpPort4500NatTimeoutSeconds == that.mMinUdpPort4500NatTimeoutSeconds;
}
/** {@inheritDoc} */
@@ -110,11 +134,14 @@ public class VcnTransportInfo implements TransportInfo, Parcelable {
@NonNull
public TransportInfo makeCopy(long redactions) {
if ((redactions & NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS) != 0) {
return new VcnTransportInfo(null, INVALID_SUBSCRIPTION_ID);
return new VcnTransportInfo(
null, INVALID_SUBSCRIPTION_ID, MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET);
}
return new VcnTransportInfo(
(mWifiInfo == null) ? null : mWifiInfo.makeCopy(redactions), mSubId);
(mWifiInfo == null) ? null : mWifiInfo.makeCopy(redactions),
mSubId,
mMinUdpPort4500NatTimeoutSeconds);
}
@Override
@@ -134,6 +161,7 @@ public class VcnTransportInfo implements TransportInfo, Parcelable {
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeInt(mSubId);
dest.writeParcelable(mWifiInfo, flags);
dest.writeInt(mMinUdpPort4500NatTimeoutSeconds);
}
@Override
@@ -146,16 +174,21 @@ public class VcnTransportInfo implements TransportInfo, Parcelable {
new Creator<VcnTransportInfo>() {
public VcnTransportInfo createFromParcel(Parcel in) {
final int subId = in.readInt();
final WifiInfo wifiInfo = in.readParcelable(null, android.net.wifi.WifiInfo.class);
final WifiInfo wifiInfo =
in.readParcelable(null, android.net.wifi.WifiInfo.class);
final int minUdpPort4500NatTimeoutSeconds = in.readInt();
// If all fields are their null values, return null TransportInfo to avoid
// leaking information about this being a VCN Network (instead of macro
// cellular, etc)
if (wifiInfo == null && subId == INVALID_SUBSCRIPTION_ID) {
if (wifiInfo == null
&& subId == INVALID_SUBSCRIPTION_ID
&& minUdpPort4500NatTimeoutSeconds
== MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET) {
return null;
}
return new VcnTransportInfo(wifiInfo, subId);
return new VcnTransportInfo(wifiInfo, subId, minUdpPort4500NatTimeoutSeconds);
}
public VcnTransportInfo[] newArray(int size) {

View File

@@ -2255,12 +2255,18 @@ public class VcnGatewayConnection extends StateMachine {
if (underlyingCaps.hasTransport(TRANSPORT_WIFI)
&& underlyingCaps.getTransportInfo() instanceof WifiInfo) {
final WifiInfo wifiInfo = (WifiInfo) underlyingCaps.getTransportInfo();
builder.setTransportInfo(new VcnTransportInfo(wifiInfo));
builder.setTransportInfo(
new VcnTransportInfo(
wifiInfo,
gatewayConnectionConfig.getMinUdpPort4500NatTimeoutSeconds()));
} else if (underlyingCaps.hasTransport(TRANSPORT_CELLULAR)
&& underlyingCaps.getNetworkSpecifier() instanceof TelephonyNetworkSpecifier) {
final TelephonyNetworkSpecifier telNetSpecifier =
(TelephonyNetworkSpecifier) underlyingCaps.getNetworkSpecifier();
builder.setTransportInfo(new VcnTransportInfo(telNetSpecifier.getSubscriptionId()));
builder.setTransportInfo(
new VcnTransportInfo(
telNetSpecifier.getSubscriptionId(),
gatewayConnectionConfig.getMinUdpPort4500NatTimeoutSeconds()));
} else {
Slog.wtf(
TAG,

View File

@@ -82,6 +82,7 @@ public class VcnGatewayConnectionConfigTest {
TimeUnit.MINUTES.toMillis(30)
};
public static final int MAX_MTU = 1360;
public static final int MIN_UDP_PORT_4500_NAT_TIMEOUT = 120;
private static final Set<Integer> GATEWAY_OPTIONS =
Collections.singleton(VCN_GATEWAY_OPTION_ENABLE_DATA_STALL_RECOVERY_WITH_MOBILITY);
@@ -104,7 +105,9 @@ public class VcnGatewayConnectionConfigTest {
public static VcnGatewayConnectionConfig buildTestConfig(
List<VcnUnderlyingNetworkTemplate> nwTemplates) {
final VcnGatewayConnectionConfig.Builder builder =
newBuilder().setVcnUnderlyingNetworkPriorities(nwTemplates);
newBuilder()
.setVcnUnderlyingNetworkPriorities(nwTemplates)
.setMinUdpPort4500NatTimeoutSeconds(MIN_UDP_PORT_4500_NAT_TIMEOUT);
return buildTestConfigWithExposedCaps(builder, EXPOSED_CAPS);
}

View File

@@ -19,6 +19,7 @@ package android.net.vcn;
import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION;
import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
import static android.net.NetworkCapabilities.REDACT_NONE;
import static android.net.vcn.VcnGatewayConnectionConfig.MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
import static org.junit.Assert.assertEquals;
@@ -37,11 +38,14 @@ import java.util.Arrays;
public class VcnTransportInfoTest {
private static final int SUB_ID = 1;
private static final int NETWORK_ID = 5;
private static final int MIN_UDP_PORT_4500_NAT_TIMEOUT = 120;
private static final WifiInfo WIFI_INFO =
new WifiInfo.Builder().setNetworkId(NETWORK_ID).build();
private static final VcnTransportInfo CELL_UNDERLYING_INFO = new VcnTransportInfo(SUB_ID);
private static final VcnTransportInfo WIFI_UNDERLYING_INFO = new VcnTransportInfo(WIFI_INFO);
private static final VcnTransportInfo CELL_UNDERLYING_INFO =
new VcnTransportInfo(SUB_ID, MIN_UDP_PORT_4500_NAT_TIMEOUT);
private static final VcnTransportInfo WIFI_UNDERLYING_INFO =
new VcnTransportInfo(WIFI_INFO, MIN_UDP_PORT_4500_NAT_TIMEOUT);
@Test
public void testGetWifiInfo() {
@@ -57,6 +61,16 @@ public class VcnTransportInfoTest {
assertEquals(INVALID_SUBSCRIPTION_ID, WIFI_UNDERLYING_INFO.getSubId());
}
@Test
public void testGetMinUdpPort4500NatTimeoutSeconds() {
assertEquals(
MIN_UDP_PORT_4500_NAT_TIMEOUT,
CELL_UNDERLYING_INFO.getMinUdpPort4500NatTimeoutSeconds());
assertEquals(
MIN_UDP_PORT_4500_NAT_TIMEOUT,
WIFI_UNDERLYING_INFO.getMinUdpPort4500NatTimeoutSeconds());
}
@Test
public void testMakeCopyRedactForNetworkSettings() {
for (VcnTransportInfo info : Arrays.asList(CELL_UNDERLYING_INFO, WIFI_UNDERLYING_INFO)) {
@@ -67,6 +81,10 @@ public class VcnTransportInfoTest {
assertNull(
((VcnTransportInfo) info.makeCopy(REDACT_FOR_NETWORK_SETTINGS))
.getWifiInfo());
assertEquals(
MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET,
((VcnTransportInfo) info.makeCopy(REDACT_FOR_NETWORK_SETTINGS))
.getMinUdpPort4500NatTimeoutSeconds());
}
}
@@ -76,10 +94,18 @@ public class VcnTransportInfoTest {
SUB_ID,
((VcnTransportInfo) CELL_UNDERLYING_INFO.makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION))
.getSubId());
assertEquals(
MIN_UDP_PORT_4500_NAT_TIMEOUT,
((VcnTransportInfo) CELL_UNDERLYING_INFO.makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION))
.getMinUdpPort4500NatTimeoutSeconds());
assertEquals(
WifiConfiguration.INVALID_NETWORK_ID,
((VcnTransportInfo) WIFI_UNDERLYING_INFO.makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION))
.getWifiInfo().getNetworkId());
assertEquals(
MIN_UDP_PORT_4500_NAT_TIMEOUT,
((VcnTransportInfo) WIFI_UNDERLYING_INFO.makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION))
.getMinUdpPort4500NatTimeoutSeconds());
}
@Test
@@ -110,8 +136,12 @@ public class VcnTransportInfoTest {
public void testParcelNotRedactedForSysUi() {
VcnTransportInfo cellRedacted = parcelForSysUi(CELL_UNDERLYING_INFO);
assertEquals(SUB_ID, cellRedacted.getSubId());
assertEquals(
MIN_UDP_PORT_4500_NAT_TIMEOUT, cellRedacted.getMinUdpPort4500NatTimeoutSeconds());
VcnTransportInfo wifiRedacted = parcelForSysUi(WIFI_UNDERLYING_INFO);
assertEquals(NETWORK_ID, wifiRedacted.getWifiInfo().getNetworkId());
assertEquals(
MIN_UDP_PORT_4500_NAT_TIMEOUT, wifiRedacted.getMinUdpPort4500NatTimeoutSeconds());
}
private VcnTransportInfo parcelForSysUi(VcnTransportInfo vcnTransportInfo) {

View File

@@ -25,6 +25,7 @@ import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED;
import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_TEMPORARY_FAILURE;
import static android.net.vcn.VcnGatewayConnectionConfigTest.MIN_UDP_PORT_4500_NAT_TIMEOUT;
import static android.net.vcn.VcnManager.VCN_ERROR_CODE_CONFIG_ERROR;
import static android.net.vcn.VcnManager.VCN_ERROR_CODE_INTERNAL_ERROR;
import static android.net.vcn.VcnManager.VCN_ERROR_CODE_NETWORK_ERROR;
@@ -66,6 +67,7 @@ import android.net.ipsec.ike.exceptions.IkeProtocolException;
import android.net.vcn.VcnGatewayConnectionConfig;
import android.net.vcn.VcnGatewayConnectionConfigTest;
import android.net.vcn.VcnManager.VcnErrorCode;
import android.net.vcn.VcnTransportInfo;
import android.os.PersistableBundle;
import androidx.test.filters.SmallTest;
@@ -425,6 +427,12 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
assertTrue(nc.hasCapability(cap));
}
assertTrue(nc.getTransportInfo() instanceof VcnTransportInfo);
final VcnTransportInfo vcnTransportInfo = (VcnTransportInfo) nc.getTransportInfo();
assertEquals(
MIN_UDP_PORT_4500_NAT_TIMEOUT,
vcnTransportInfo.getMinUdpPort4500NatTimeoutSeconds());
// Now that Vcn Network is up, notify it as validated and verify the SafeMode alarm is
// canceled
triggerValidation(NetworkAgent.VALIDATION_STATUS_VALID);

View File

@@ -16,6 +16,8 @@
package com.android.server.vcn;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static com.android.server.vcn.VcnGatewayConnection.VcnIkeSession;
import static com.android.server.vcn.VcnGatewayConnection.VcnNetworkAgent;
import static com.android.server.vcn.VcnTestUtils.setupIpSecManager;
@@ -46,6 +48,7 @@ import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.TelephonyNetworkSpecifier;
import android.net.ipsec.ike.ChildSessionCallback;
import android.net.ipsec.ike.IkeSessionCallback;
import android.net.ipsec.ike.IkeSessionConfiguration;
@@ -127,7 +130,10 @@ public class VcnGatewayConnectionTestBase {
protected static final UnderlyingNetworkRecord TEST_UNDERLYING_NETWORK_RECORD_1 =
getTestNetworkRecord(
mock(Network.class, CALLS_REAL_METHODS),
new NetworkCapabilities(),
new NetworkCapabilities.Builder()
.addTransportType(TRANSPORT_CELLULAR)
.setNetworkSpecifier(new TelephonyNetworkSpecifier(TEST_SUB_ID))
.build(),
new LinkProperties(),
false /* blocked */);