1 #!/bin/bash 2 3 # Kernel configuration options. 4 OPTIONS=" DEBUG_SPINLOCK DEBUG_ATOMIC_SLEEP DEBUG_MUTEXES DEBUG_RT_MUTEXES" 5 OPTIONS="$OPTIONS IPV6 IPV6_ROUTER_PREF IPV6_MULTIPLE_TABLES IPV6_ROUTE_INFO" 6 OPTIONS="$OPTIONS TUN SYN_COOKIES IP_ADVANCED_ROUTER IP_MULTIPLE_TABLES" 7 OPTIONS="$OPTIONS NETFILTER NETFILTER_ADVANCED NETFILTER_XTABLES" 8 OPTIONS="$OPTIONS NETFILTER_XT_MARK NETFILTER_XT_TARGET_MARK" 9 OPTIONS="$OPTIONS IP_NF_IPTABLES IP_NF_MANGLE IP_NF_FILTER" 10 OPTIONS="$OPTIONS IP6_NF_IPTABLES IP6_NF_MANGLE IP6_NF_FILTER INET6_IPCOMP" 11 OPTIONS="$OPTIONS IPV6_PRIVACY IPV6_OPTIMISTIC_DAD" 12 OPTIONS="$OPTIONS CONFIG_IPV6_ROUTE_INFO CONFIG_IPV6_ROUTER_PREF" 13 OPTIONS="$OPTIONS CONFIG_NETFILTER_XT_TARGET_NFLOG" 14 OPTIONS="$OPTIONS CONFIG_NETFILTER_XT_MATCH_QUOTA" 15 OPTIONS="$OPTIONS CONFIG_NETFILTER_XT_MATCH_QUOTA2" 16 OPTIONS="$OPTIONS CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG" 17 OPTIONS="$OPTIONS CONFIG_NETFILTER_TPROXY" 18 OPTIONS="$OPTIONS CONFIG_NETFILTER_XT_MATCH_SOCKET" 19 OPTIONS="$OPTIONS CONFIG_NETFILTER_XT_MATCH_QTAGUID" 20 # For 4.14 CONFIG_NETFILTER_XT_MATCH_SOCKET demands CONFIG_NF_SOCKET_IPV4/6 21 OPTIONS="$OPTIONS CONFIG_NF_SOCKET_IPV4 CONFIG_NF_SOCKET_IPV6" 22 OPTIONS="$OPTIONS CONFIG_INET_UDP_DIAG CONFIG_INET_DIAG_DESTROY" 23 OPTIONS="$OPTIONS IP_SCTP INET_SCTP_DIAG" 24 OPTIONS="$OPTIONS CONFIG_IP_NF_TARGET_REJECT CONFIG_IP_NF_TARGET_REJECT_SKERR" 25 OPTIONS="$OPTIONS CONFIG_IP6_NF_TARGET_REJECT CONFIG_IP6_NF_TARGET_REJECT_SKERR" 26 OPTIONS="$OPTIONS BPF_SYSCALL NET_KEY XFRM_USER XFRM_STATISTICS CRYPTO_CBC" 27 OPTIONS="$OPTIONS CRYPTO_CTR CRYPTO_HMAC CRYPTO_AES CRYPTO_SHA1 CRYPTO_SHA256" 28 OPTIONS="$OPTIONS CRYPTO_SHA12 CRYPTO_USER INET_AH INET_ESP INET_XFRM_MODE" 29 OPTIONS="$OPTIONS TRANSPORT INET_XFRM_MODE_TUNNEL INET6_AH INET6_ESP" 30 OPTIONS="$OPTIONS INET6_XFRM_MODE_TRANSPORT INET6_XFRM_MODE_TUNNEL" 31 OPTIONS="$OPTIONS CRYPTO_SHA256 CRYPTO_SHA512 CRYPTO_AES_X86_64 CRYPTO_NULL" 32 OPTIONS="$OPTIONS CRYPTO_GCM CRYPTO_ECHAINIV NET_IPVTI IPV6_VTI" 33 OPTIONS="$OPTIONS SOCK_CGROUP_DATA CGROUP_BPF" 34 35 # For 4.14 kernels, where UBD and HOSTFS are not set 36 OPTIONS="$OPTIONS CONFIG_BLK_DEV_UBD CONFIG_HOSTFS" 37 38 # For 3.1 kernels, where devtmpfs is not on by default. 39 OPTIONS="$OPTIONS DEVTMPFS DEVTMPFS_MOUNT" 40 41 # These two break the flo kernel due to differences in -Werror on recent GCC. 42 DISABLE_OPTIONS=" CONFIG_REISERFS_FS CONFIG_ANDROID_PMEM" 43 # This one breaks the fugu kernel due to a nonexistent sem_wait_array. 44 DISABLE_OPTIONS="$DISABLE_OPTIONS CONFIG_SYSVIPC" 45 46 # How many TAP interfaces to create to provide the VM with real network access 47 # via the host. This requires privileges (e.g., root access) on the host. 48 # 49 # This is not needed to run the tests, but can be used, for example, to allow 50 # the VM to update system packages, or to write tests that need access to a 51 # real network. The VM does not set up networking by default, but it contains a 52 # DHCP client and has the ability to use IPv6 autoconfiguration. This script 53 # does not perform any host-level setup beyond configuring tap interfaces; 54 # configuring IPv4 NAT and/or IPv6 router advertisements or ND proxying must 55 # be done separately. 56 NUMTAPINTERFACES=0 57 58 # The root filesystem disk image we'll use. 59 ROOTFS=net_test.rootfs.20150203 60 COMPRESSED_ROOTFS=$ROOTFS.xz 61 URL=https://dl.google.com/dl/android/$COMPRESSED_ROOTFS 62 63 # Parse arguments and figure out which test to run. 64 J=${J:-64} 65 MAKE="make" 66 OUT_DIR=$(readlink -f ${OUT_DIR:-.}) 67 KERNEL_DIR=$(readlink -f ${KERNEL_DIR:-.}) 68 if [ "$OUT_DIR" != "$KERNEL_DIR" ]; then 69 MAKE="$MAKE O=$OUT_DIR" 70 fi 71 SCRIPT_DIR=$(dirname $(readlink -f $0)) 72 CONFIG_SCRIPT=${KERNEL_DIR}/scripts/config 73 CONFIG_FILE=${OUT_DIR}/.config 74 consolemode= 75 testmode= 76 blockdevice=ubda 77 nobuild=0 78 norun=0 79 80 while [ -n "$1" ]; do 81 if [ "$1" = "--builder" ]; then 82 consolemode="con=null,fd:1" 83 testmode=builder 84 shift 85 elif [ "$1" == "--readonly" ]; then 86 blockdevice="${blockdevice}r" 87 shift 88 elif [ "$1" == "--nobuild" ]; then 89 nobuild=1 90 shift 91 elif [ "$1" == "--norun" ]; then 92 norun=1 93 shift 94 else 95 test=$1 96 break # Arguments after the test file are passed to the test itself. 97 fi 98 done 99 100 # Check that test file exists and is readable 101 test_file=$SCRIPT_DIR/$test 102 if [[ ! -e $test_file ]]; then 103 echo "test file '${test_file}' does not exist" 104 exit 1 105 fi 106 107 if [[ ! -x $test_file ]]; then 108 echo "test file '${test_file}' is not executable" 109 exit 1 110 fi 111 112 # Collect trailing arguments to pass to $test 113 test_args=${@:2} 114 115 function isRunningTest() { 116 [[ -n "$test" ]] && ! (( norun )) 117 } 118 119 function isBuildOnly() { 120 [[ -z "$test" ]] && (( norun )) && ! (( nobuild )) 121 } 122 123 if ! isRunningTest && ! isBuildOnly; then 124 echo "Usage:" >&2 125 echo " $0 [--builder] [--readonly] [--nobuild] <test>" >&2 126 echo " $0 --norun" >&2 127 exit 1 128 fi 129 130 cd $OUT_DIR 131 echo Running tests from: `pwd` 132 133 set -e 134 135 # Check if we need to uncompress the disk image. 136 # We use xz because it compresses better: to 42M vs 72M (gzip) / 62M (bzip2). 137 cd $SCRIPT_DIR 138 if [ ! -f $ROOTFS ]; then 139 echo "Deleting $COMPRESSED_ROOTFS" >&2 140 rm -f $COMPRESSED_ROOTFS 141 echo "Downloading $URL" >&2 142 wget -nv $URL 143 echo "Uncompressing $COMPRESSED_ROOTFS" >&2 144 unxz $COMPRESSED_ROOTFS 145 fi 146 echo "Using $ROOTFS" 147 cd - 148 149 # If network access was requested, create NUMTAPINTERFACES tap interfaces on 150 # the host, and prepare UML command line params to use them. The interfaces are 151 # called <user>TAP0, <user>TAP1, on the host, and eth0, eth1, ..., in the VM. 152 if (( $NUMTAPINTERFACES > 0 )); then 153 user=${USER:0:10} 154 tapinterfaces= 155 netconfig= 156 for id in $(seq 0 $(( NUMTAPINTERFACES - 1 )) ); do 157 tap=${user}TAP$id 158 tapinterfaces="$tapinterfaces $tap" 159 mac=$(printf fe:fd:00:00:00:%02x $id) 160 netconfig="$netconfig eth$id=tuntap,$tap,$mac" 161 done 162 163 for tap in $tapinterfaces; do 164 if ! ip link list $tap > /dev/null; then 165 echo "Creating tap interface $tap" >&2 166 sudo tunctl -u $USER -t $tap 167 sudo ip link set $tap up 168 fi 169 done 170 fi 171 172 if [ -n "$KERNEL_BINARY" ]; then 173 nobuild=1 174 else 175 KERNEL_BINARY=./linux 176 fi 177 178 if ((nobuild == 0)); then 179 # Exporting ARCH=um SUBARCH=x86_64 doesn't seem to work, as it "sometimes" 180 # (?) results in a 32-bit kernel. 181 182 # If there's no kernel config at all, create one or UML won't work. 183 [ -f $CONFIG_FILE ] || (cd $KERNEL_DIR && $MAKE defconfig ARCH=um SUBARCH=x86_64) 184 185 # Enable the kernel config options listed in $OPTIONS. 186 cmdline=${OPTIONS// / -e } 187 $CONFIG_SCRIPT --file $CONFIG_FILE $cmdline 188 189 # Disable the kernel config options listed in $DISABLE_OPTIONS. 190 cmdline=${DISABLE_OPTIONS// / -d } 191 $CONFIG_SCRIPT --file $CONFIG_FILE $cmdline 192 193 # olddefconfig doesn't work on old kernels. 194 if ! $MAKE olddefconfig ARCH=um SUBARCH=x86_64 CROSS_COMPILE= ; then 195 cat >&2 << EOF 196 197 Warning: "make olddefconfig" failed. 198 Perhaps this kernel is too old to support it. 199 You may get asked lots of questions. 200 Keep enter pressed to accept the defaults. 201 202 EOF 203 fi 204 205 # Compile the kernel. 206 $MAKE -j$J linux ARCH=um SUBARCH=x86_64 CROSS_COMPILE= 207 fi 208 209 if (( norun == 1 )); then 210 exit 0 211 fi 212 213 # Get the absolute path to the test file that's being run. 214 dir=/host$SCRIPT_DIR 215 216 # Start the VM. 217 exec $KERNEL_BINARY umid=net_test $blockdevice=$SCRIPT_DIR/$ROOTFS \ 218 mem=512M init=/sbin/net_test.sh net_test=$dir/$test \ 219 net_test_args=\"$test_args\" \ 220 net_test_mode=$testmode $netconfig $consolemode >&2 221