diff --git a/Vcn/service-b/src/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java b/Vcn/service-b/src/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java index 206523a6e9..3619253749 100644 --- a/Vcn/service-b/src/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java +++ b/Vcn/service-b/src/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java @@ -64,6 +64,12 @@ public class IpSecPacketLossDetector extends NetworkMetricMonitor { private static final int PACKET_LOSS_PERCENT_UNAVAILABLE = -1; + // Ignore the packet loss detection result if the expected packet number is smaller than 10. + // Solarwinds NPM uses 10 ICMP echos to calculate packet loss rate (as per + // https://thwack.solarwinds.com/products/network-performance-monitor-npm/f/forum/63829/how-is-packet-loss-calculated) + @VisibleForTesting(visibility = Visibility.PRIVATE) + static final int MIN_VALID_EXPECTED_RX_PACKET_NUM = 10; + @Retention(RetentionPolicy.SOURCE) @IntDef( prefix = {"PACKET_LOSS_"}, @@ -85,6 +91,8 @@ public class IpSecPacketLossDetector extends NetworkMetricMonitor { * */ @@ -113,7 +121,7 @@ public class IpSecPacketLossDetector extends NetworkMetricMonitor { private static final int MAX_SEQ_NUM_INCREASE_DEFAULT_DISABLED = -1; private long mPollIpSecStateIntervalMs; - private final int mPacketLossRatePercentThreshold; + private int mPacketLossRatePercentThreshold; private int mMaxSeqNumIncreasePerSecond; @NonNull private final Handler mHandler; @@ -273,6 +281,7 @@ public class IpSecPacketLossDetector extends NetworkMetricMonitor { mPollIpSecStateIntervalMs = getPollIpSecStateIntervalMs(carrierConfig); if (Flags.handleSeqNumLeap()) { + mPacketLossRatePercentThreshold = getPacketLossRatePercentThreshold(carrierConfig); mMaxSeqNumIncreasePerSecond = getMaxSeqNumIncreasePerSecond(carrierConfig); } } @@ -476,6 +485,11 @@ public class IpSecPacketLossDetector extends NetworkMetricMonitor { + " actualPktCntDiff: " + actualPktCntDiff); + if (Flags.handleSeqNumLeap() && expectedPktCntDiff < MIN_VALID_EXPECTED_RX_PACKET_NUM) { + // The sample size is too small to ensure a reliable detection result + return PacketLossCalculationResult.invalid(); + } + if (expectedPktCntDiff < 0 || expectedPktCntDiff == 0 || actualPktCntDiff < 0 diff --git a/Vcn/tests/unit/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java b/Vcn/tests/unit/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java index 68a2ad7e1a..c8b60e5c33 100644 --- a/Vcn/tests/unit/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java +++ b/Vcn/tests/unit/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java @@ -20,6 +20,7 @@ import static android.net.vcn.VcnManager.VCN_NETWORK_SELECTION_IPSEC_PACKET_LOSS import static android.net.vcn.VcnManager.VCN_NETWORK_SELECTION_MAX_SEQ_NUM_INCREASE_PER_SECOND_KEY; import static android.net.vcn.VcnManager.VCN_NETWORK_SELECTION_POLL_IPSEC_STATE_INTERVAL_SECONDS_KEY; +import static com.android.server.vcn.routeselection.IpSecPacketLossDetector.MIN_VALID_EXPECTED_RX_PACKET_NUM; import static com.android.server.vcn.routeselection.IpSecPacketLossDetector.getMaxSeqNumIncreasePerSecond; import static com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper; @@ -436,6 +437,21 @@ public class IpSecPacketLossDetectorTest extends NetworkEvaluationTestBase { mTransformStateInitial, 3000, 2000, 2000, PacketLossCalculationResult.invalid()); } + @Test + public void testGetPacketLossRate_expectedPacketNumTooFew() throws Exception { + final int oldRxNo = 4096; + final int oldPktCnt = 4096; + final int pktCntDiff = MIN_VALID_EXPECTED_RX_PACKET_NUM - 1; + final byte[] bitmapReceiveAll = newReplayBitmap(4096); + + final IpSecTransformState oldState = + newTransformState(oldRxNo, oldPktCnt, bitmapReceiveAll); + final IpSecTransformState newState = + newTransformState(oldRxNo + pktCntDiff, oldPktCnt + pktCntDiff, bitmapReceiveAll); + + checkGetPacketLossRate(oldState, newState, PacketLossCalculationResult.invalid()); + } + @Test public void testGetPacketLossRate_againstInitialState() throws Exception { checkGetPacketLossRate(mTransformStateInitial, 7000, 7001, 4096, 0);