1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.security.cts; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertTrue; 21 import static org.junit.Assume.assumeTrue; 22 23 import com.android.modules.utils.build.testing.DeviceSdkLevel; 24 import com.android.tradefed.build.IBuildInfo; 25 import com.android.tradefed.device.ITestDevice; 26 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; 27 import com.android.tradefed.testtype.IBuildReceiver; 28 import com.android.tradefed.testtype.IDeviceTest; 29 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; 30 31 import org.junit.Before; 32 import org.junit.Test; 33 import org.junit.runner.RunWith; 34 35 import java.util.ArrayList; 36 import java.util.Arrays; 37 import java.util.List; 38 39 /** 40 * Host-side tests for values in /proc/net. 41 * 42 * These tests analyze /proc/net to verify that certain networking properties are correct. 43 */ 44 @RunWith(DeviceJUnit4ClassRunner.class) 45 public class ProcNetTest extends BaseHostJUnit4Test implements IBuildReceiver, IDeviceTest { 46 private static final String SPI_TIMEOUT_SYSCTL = "/proc/sys/net/core/xfrm_acq_expires"; 47 private static final int MIN_ACQ_EXPIRES = 3600; 48 // Global sysctls. Must be present and set to 1. 49 private static final String[] GLOBAL_SYSCTLS = { 50 "/proc/sys/net/ipv4/fwmark_reflect", 51 "/proc/sys/net/ipv6/fwmark_reflect", 52 "/proc/sys/net/ipv4/tcp_fwmark_accept", 53 }; 54 55 // Per-interface IPv6 autoconf sysctls. 56 private static final String IPV6_SYSCTL_DIR = "/proc/sys/net/ipv6/conf"; 57 private static final String AUTOCONF_SYSCTL = "accept_ra_rt_table"; 58 59 // Expected values for MIN|MAX_PLEN. 60 private static final String ACCEPT_RA_RT_INFO_MIN_PLEN_STRING = "accept_ra_rt_info_min_plen"; 61 private static final int ACCEPT_RA_RT_INFO_MIN_PLEN_VALUE = 48; 62 private static final String ACCEPT_RA_RT_INFO_MAX_PLEN_STRING = "accept_ra_rt_info_max_plen"; 63 private static final int ACCEPT_RA_RT_INFO_MAX_PLEN_VALUE = 64; 64 // Expected values for RFC 7559 router soliciations. 65 // Maximum number of router solicitations to send. -1 means no limit. 66 private static final int IPV6_WIFI_ROUTER_SOLICITATIONS = -1; 67 private ITestDevice mDevice; 68 private IBuildInfo mBuild; 69 private String[] mSysctlDirs; 70 71 /** 72 * {@inheritDoc} 73 */ 74 @Override setBuild(IBuildInfo build)75 public void setBuild(IBuildInfo build) { 76 mBuild = build; 77 } 78 79 /** 80 * {@inheritDoc} 81 */ 82 @Override setDevice(ITestDevice device)83 public void setDevice(ITestDevice device) { 84 mDevice = device; 85 } 86 87 /** Run before each test case. */ 88 @Before setUp()89 public void setUp() throws Exception { 90 mSysctlDirs = getSysctlDirs(); 91 } 92 getSysctlDirs()93 private String[] getSysctlDirs() throws Exception { 94 String interfaceDirs[] = mDevice.executeAdbCommand("shell", "ls", "-1", 95 IPV6_SYSCTL_DIR).split("\n"); 96 List<String> interfaceDirsList = new ArrayList<String>(Arrays.asList(interfaceDirs)); 97 interfaceDirsList.remove("all"); 98 interfaceDirsList.remove("lo"); 99 return interfaceDirsList.toArray(new String[interfaceDirsList.size()]); 100 } 101 102 assertLess(String sysctl, int a, int b)103 protected void assertLess(String sysctl, int a, int b) { 104 assertTrue("value of " + sysctl + ": expected < " + b + " but was: " + a, a < b); 105 } 106 assertAtLeast(String sysctl, int a, int b)107 protected void assertAtLeast(String sysctl, int a, int b) { 108 assertTrue("value of " + sysctl + ": expected >= " + b + " but was: " + a, a >= b); 109 } 110 readIntFromPath(String path)111 public int readIntFromPath(String path) throws Exception { 112 String mode = mDevice.executeAdbCommand("shell", "stat", "-c", "%a", path).trim(); 113 String user = mDevice.executeAdbCommand("shell", "stat", "-c", "%u", path).trim(); 114 String group = mDevice.executeAdbCommand("shell", "stat", "-c", "%g", path).trim(); 115 assertEquals(mode, "644"); 116 assertEquals(user, "0"); 117 assertEquals(group, "0"); 118 return Integer.parseInt(mDevice.executeAdbCommand("shell", "cat", path).trim()); 119 } 120 121 /** 122 * Checks that SPI default timeouts are overridden, and set to a reasonable length of time 123 */ 124 @Test testMinAcqExpires()125 public void testMinAcqExpires() throws Exception { 126 int value = readIntFromPath(SPI_TIMEOUT_SYSCTL); 127 assertAtLeast(SPI_TIMEOUT_SYSCTL, value, MIN_ACQ_EXPIRES); 128 } 129 130 /** 131 * Checks that the sysctls for multinetwork kernel features are present and 132 * enabled. 133 */ 134 @Test testProcSysctls()135 public void testProcSysctls() throws Exception { 136 for (String sysctl : GLOBAL_SYSCTLS) { 137 int value = readIntFromPath(sysctl); 138 assertEquals(sysctl, 1, value); 139 } 140 141 for (String interfaceDir : mSysctlDirs) { 142 String path = IPV6_SYSCTL_DIR + "/" + interfaceDir + "/" + AUTOCONF_SYSCTL; 143 int value = readIntFromPath(path); 144 assertLess(path, value, 0); 145 } 146 } 147 148 /** 149 * Verify that accept_ra_rt_info_{min,max}_plen exists and is set to the expected value 150 */ 151 @Test testAcceptRaRtInfoMinMaxPlen()152 public void testAcceptRaRtInfoMinMaxPlen() throws Exception { 153 for (String interfaceDir : mSysctlDirs) { 154 String path = IPV6_SYSCTL_DIR + "/" + interfaceDir + "/" + "accept_ra_rt_info_min_plen"; 155 int value = readIntFromPath(path); 156 assertEquals(path, value, ACCEPT_RA_RT_INFO_MIN_PLEN_VALUE); 157 path = IPV6_SYSCTL_DIR + "/" + interfaceDir + "/" + "accept_ra_rt_info_max_plen"; 158 value = readIntFromPath(path); 159 assertEquals(path, value, ACCEPT_RA_RT_INFO_MAX_PLEN_VALUE); 160 } 161 } 162 163 /** 164 * Verify that router_solicitations exists and is set to the expected value 165 * and verify that router_solicitation_max_interval exists and is in an acceptable interval. 166 */ 167 @Test testRouterSolicitations()168 public void testRouterSolicitations() throws Exception { 169 for (String interfaceDir : mSysctlDirs) { 170 String path = IPV6_SYSCTL_DIR + "/" + interfaceDir + "/" + "router_solicitations"; 171 int value = readIntFromPath(path); 172 assertEquals(path, IPV6_WIFI_ROUTER_SOLICITATIONS, value); 173 path = IPV6_SYSCTL_DIR + "/" + interfaceDir + "/" + "router_solicitation_max_interval"; 174 int interval = readIntFromPath(path); 175 final int lowerBoundSec = 15 * 60; 176 final int upperBoundSec = 60 * 60; 177 assertTrue(path, lowerBoundSec <= interval); 178 assertTrue(path, interval <= upperBoundSec); 179 } 180 } 181 182 /** 183 * Verify that cubic is used as the congestion control algorithm. 184 * (This repeats the VTS test, and is here for good performance of the internet as a whole.) 185 * TODO: revisit this once a better CC algorithm like BBR2 is available. 186 */ 187 @Test testCongestionControl()188 public void testCongestionControl() throws Exception { 189 final DeviceSdkLevel dsl = new DeviceSdkLevel(mDevice); 190 assumeTrue(dsl.isDeviceAtLeastV()); 191 192 String path = "/proc/sys/net/ipv4/tcp_congestion_control"; 193 String value = mDevice.executeAdbCommand("shell", "cat", path).trim(); 194 assertEquals("cubic", value); 195 } 196 } 197