16ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo Colitti#!/bin/bash
26ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo Colitti
3f957a48b5a4d51bcb06a3b77f4152e592c00fbc6Lorenzo Colitti# Kernel configuration options.
4a5f7e58861cef7672474e10a14fee7ee7e3b3154Lorenzo ColittiOPTIONS=" DEBUG_SPINLOCK DEBUG_ATOMIC_SLEEP DEBUG_MUTEXES DEBUG_RT_MUTEXES"
5a5f7e58861cef7672474e10a14fee7ee7e3b3154Lorenzo ColittiOPTIONS="$OPTIONS IPV6 IPV6_ROUTER_PREF IPV6_MULTIPLE_TABLES IPV6_ROUTE_INFO"
6a25ebd97dd121c7f89e59fa440b86ffc9822d012Lorenzo ColittiOPTIONS="$OPTIONS TUN SYN_COOKIES IP_ADVANCED_ROUTER IP_MULTIPLE_TABLES"
76ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo ColittiOPTIONS="$OPTIONS NETFILTER NETFILTER_ADVANCED NETFILTER_XTABLES"
86ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo ColittiOPTIONS="$OPTIONS NETFILTER_XT_MARK NETFILTER_XT_TARGET_MARK"
96ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo ColittiOPTIONS="$OPTIONS IP_NF_IPTABLES IP_NF_MANGLE"
10d7c3975614112794fccf8a576d442c19e801daa8Lorenzo ColittiOPTIONS="$OPTIONS IP6_NF_IPTABLES IP6_NF_MANGLE INET6_IPCOMP"
11ea56ba43a8234d545e8e22a09577850972764149Erik KlineOPTIONS="$OPTIONS IPV6_PRIVACY IPV6_OPTIMISTIC_DAD"
12687e9aeed016ad1773583bd8b478b861480e8243Lorenzo ColittiOPTIONS="$OPTIONS CONFIG_NETFILTER_XT_TARGET_NFLOG"
13687e9aeed016ad1773583bd8b478b861480e8243Lorenzo ColittiOPTIONS="$OPTIONS CONFIG_NETFILTER_XT_MATCH_QUOTA CONFIG_NETFILTER_XT_MATCH_QUOTA2"
14687e9aeed016ad1773583bd8b478b861480e8243Lorenzo ColittiOPTIONS="$OPTIONS CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG"
153823b47a664a64024278c1fa0cbc1b632cc60634Lorenzo ColittiOPTIONS="$OPTIONS CONFIG_INET_UDP_DIAG CONFIG_INET_DIAG_DESTROY"
16687e9aeed016ad1773583bd8b478b861480e8243Lorenzo Colitti
17d7c3975614112794fccf8a576d442c19e801daa8Lorenzo Colitti# For 3.1 kernels, where devtmpfs is not on by default.
18d7c3975614112794fccf8a576d442c19e801daa8Lorenzo ColittiOPTIONS="$OPTIONS DEVTMPFS DEVTMPFS_MOUNT"
196ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo Colitti
20f957a48b5a4d51bcb06a3b77f4152e592c00fbc6Lorenzo Colitti# These two break the flo kernel due to differences in -Werror on recent GCC.
21f957a48b5a4d51bcb06a3b77f4152e592c00fbc6Lorenzo ColittiDISABLE_OPTIONS=" CONFIG_REISERFS_FS CONFIG_ANDROID_PMEM"
22f957a48b5a4d51bcb06a3b77f4152e592c00fbc6Lorenzo Colitti
23fdb9c0b54ff355ade3507c363cfa6641c02b4f2bLorenzo Colitti# How many TAP interfaces to create to provide the VM with real network access
24fdb9c0b54ff355ade3507c363cfa6641c02b4f2bLorenzo Colitti# via the host. This requires privileges (e.g., root access) on the host.
25fdb9c0b54ff355ade3507c363cfa6641c02b4f2bLorenzo Colitti#
26fdb9c0b54ff355ade3507c363cfa6641c02b4f2bLorenzo Colitti# This is not needed to run the tests, but can be used, for example, to allow
27fdb9c0b54ff355ade3507c363cfa6641c02b4f2bLorenzo Colitti# the VM to update system packages, or to write tests that need access to a
28fdb9c0b54ff355ade3507c363cfa6641c02b4f2bLorenzo Colitti# real network. The VM does not set up networking by default, but it contains a
29fdb9c0b54ff355ade3507c363cfa6641c02b4f2bLorenzo Colitti# DHCP client and has the ability to use IPv6 autoconfiguration. This script
30fdb9c0b54ff355ade3507c363cfa6641c02b4f2bLorenzo Colitti# does not perform any host-level setup beyond configuring tap interfaces;
31fdb9c0b54ff355ade3507c363cfa6641c02b4f2bLorenzo Colitti# configuring IPv4 NAT and/or IPv6 router advertisements or ND proxying must
32fdb9c0b54ff355ade3507c363cfa6641c02b4f2bLorenzo Colitti# be done separately.
33fdb9c0b54ff355ade3507c363cfa6641c02b4f2bLorenzo ColittiNUMTAPINTERFACES=0
346ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo Colitti
356ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo Colitti# The root filesystem disk image we'll use.
36f4b4c0973689190659ff972f52305a99f983fb3dLorenzo ColittiROOTFS=net_test.rootfs.20150203
37f4b4c0973689190659ff972f52305a99f983fb3dLorenzo ColittiCOMPRESSED_ROOTFS=$ROOTFS.xz
38f4b4c0973689190659ff972f52305a99f983fb3dLorenzo ColittiURL=https://dl.google.com/dl/android/$COMPRESSED_ROOTFS
396ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo Colitti
406ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo Colitti# Figure out which test to run.
416ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo Colittiif [ -z "$1" ]; then
426ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo Colitti  echo "Usage: $0 <test>" >&2
436ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo Colitti  exit 1
446ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo Colittifi
456ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo Colittitest=$1
466ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo Colitti
476ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo Colittiset -e
486ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo Colitti
496ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo Colitti# Check if we need to uncompress the disk image.
506ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo Colitti# We use xz because it compresses better: to 42M vs 72M (gzip) / 62M (bzip2).
51f4b4c0973689190659ff972f52305a99f983fb3dLorenzo Colitticd $(dirname $0)
52f4b4c0973689190659ff972f52305a99f983fb3dLorenzo Colittiif [ ! -f $ROOTFS ]; then
53f4b4c0973689190659ff972f52305a99f983fb3dLorenzo Colitti  echo "Deleting $COMPRESSED_ROOTFS" >&2
54f4b4c0973689190659ff972f52305a99f983fb3dLorenzo Colitti  rm -f $COMPRESSED_ROOTFS
55f4b4c0973689190659ff972f52305a99f983fb3dLorenzo Colitti  echo "Downloading $URL" >&2
56f4b4c0973689190659ff972f52305a99f983fb3dLorenzo Colitti  wget $URL
57f4b4c0973689190659ff972f52305a99f983fb3dLorenzo Colitti  echo "Uncompressing $COMPRESSED_ROOTFS" >&2
58f4b4c0973689190659ff972f52305a99f983fb3dLorenzo Colitti  unxz $COMPRESSED_ROOTFS
596ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo Colittifi
60f4b4c0973689190659ff972f52305a99f983fb3dLorenzo Colittiecho "Using $ROOTFS"
61f4b4c0973689190659ff972f52305a99f983fb3dLorenzo Colitticd -
626ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo Colitti
63fdb9c0b54ff355ade3507c363cfa6641c02b4f2bLorenzo Colitti# If network access was requested, create NUMTAPINTERFACES tap interfaces on
64fdb9c0b54ff355ade3507c363cfa6641c02b4f2bLorenzo Colitti# the host, and prepare UML command line params to use them. The interfaces are
65fdb9c0b54ff355ade3507c363cfa6641c02b4f2bLorenzo Colitti# called <user>TAP0, <user>TAP1, on the host, and eth0, eth1, ..., in the VM.
66fdb9c0b54ff355ade3507c363cfa6641c02b4f2bLorenzo Colittiif (( $NUMTAPINTERFACES > 0 )); then
67fdb9c0b54ff355ade3507c363cfa6641c02b4f2bLorenzo Colitti  user=${USER:0:10}
68fdb9c0b54ff355ade3507c363cfa6641c02b4f2bLorenzo Colitti  tapinterfaces=
69fdb9c0b54ff355ade3507c363cfa6641c02b4f2bLorenzo Colitti  netconfig=
70fdb9c0b54ff355ade3507c363cfa6641c02b4f2bLorenzo Colitti  for id in $(seq 0 $(( NUMTAPINTERFACES - 1 )) ); do
71fdb9c0b54ff355ade3507c363cfa6641c02b4f2bLorenzo Colitti    tap=${user}TAP$id
72fdb9c0b54ff355ade3507c363cfa6641c02b4f2bLorenzo Colitti    tapinterfaces="$tapinterfaces $tap"
73fdb9c0b54ff355ade3507c363cfa6641c02b4f2bLorenzo Colitti    mac=$(printf fe:fd:00:00:00:%02x $id)
74fdb9c0b54ff355ade3507c363cfa6641c02b4f2bLorenzo Colitti    netconfig="$netconfig eth$id=tuntap,$tap,$mac"
75fdb9c0b54ff355ade3507c363cfa6641c02b4f2bLorenzo Colitti  done
766ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo Colitti
77fdb9c0b54ff355ade3507c363cfa6641c02b4f2bLorenzo Colitti  for tap in $tapinterfaces; do
78fdb9c0b54ff355ade3507c363cfa6641c02b4f2bLorenzo Colitti    if ! ip link list $tap > /dev/null; then
79fdb9c0b54ff355ade3507c363cfa6641c02b4f2bLorenzo Colitti      echo "Creating tap interface $tap" >&2
80fdb9c0b54ff355ade3507c363cfa6641c02b4f2bLorenzo Colitti      sudo tunctl -u $USER -t $tap
81fdb9c0b54ff355ade3507c363cfa6641c02b4f2bLorenzo Colitti      sudo ip link set $tap up
82fdb9c0b54ff355ade3507c363cfa6641c02b4f2bLorenzo Colitti    fi
83fdb9c0b54ff355ade3507c363cfa6641c02b4f2bLorenzo Colitti  done
84fdb9c0b54ff355ade3507c363cfa6641c02b4f2bLorenzo Colittifi
856ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo Colitti
86a9fe6b7c67383ea81aa8cbed9928dff4a517d944Lorenzo Colittiif [ -z "$KERNEL_BINARY" ]; then
87a9fe6b7c67383ea81aa8cbed9928dff4a517d944Lorenzo Colitti  # Exporting ARCH=um SUBARCH=x86_64 doesn't seem to work, as it "sometimes"
88a9fe6b7c67383ea81aa8cbed9928dff4a517d944Lorenzo Colitti  # (?) results in a 32-bit kernel.
896ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo Colitti
90a9fe6b7c67383ea81aa8cbed9928dff4a517d944Lorenzo Colitti  # If there's no kernel config at all, create one or UML won't work.
91a9fe6b7c67383ea81aa8cbed9928dff4a517d944Lorenzo Colitti  [ -f .config ] || make defconfig ARCH=um SUBARCH=x86_64
926ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo Colitti
93a9fe6b7c67383ea81aa8cbed9928dff4a517d944Lorenzo Colitti  # Enable the kernel config options listed in $OPTIONS.
94a9fe6b7c67383ea81aa8cbed9928dff4a517d944Lorenzo Colitti  cmdline=${OPTIONS// / -e }
95a9fe6b7c67383ea81aa8cbed9928dff4a517d944Lorenzo Colitti  ./scripts/config $cmdline
961eccad2f9baf2dc69e46d2ef5a6f2b6f928e185bLorenzo Colitti
97a9fe6b7c67383ea81aa8cbed9928dff4a517d944Lorenzo Colitti  # Disable the kernel config options listed in $DISABLE_OPTIONS.
98a9fe6b7c67383ea81aa8cbed9928dff4a517d944Lorenzo Colitti  cmdline=${DISABLE_OPTIONS// / -d }
99a9fe6b7c67383ea81aa8cbed9928dff4a517d944Lorenzo Colitti  ./scripts/config $cmdline
100f957a48b5a4d51bcb06a3b77f4152e592c00fbc6Lorenzo Colitti
101a9fe6b7c67383ea81aa8cbed9928dff4a517d944Lorenzo Colitti  # olddefconfig doesn't work on old kernels.
102a9fe6b7c67383ea81aa8cbed9928dff4a517d944Lorenzo Colitti  if ! make olddefconfig ARCH=um SUBARCH=x86_64 CROSS_COMPILE= ; then
103a9fe6b7c67383ea81aa8cbed9928dff4a517d944Lorenzo Colitti    cat >&2 << EOF
1041eccad2f9baf2dc69e46d2ef5a6f2b6f928e185bLorenzo Colitti
1051eccad2f9baf2dc69e46d2ef5a6f2b6f928e185bLorenzo ColittiWarning: "make olddefconfig" failed.
1061eccad2f9baf2dc69e46d2ef5a6f2b6f928e185bLorenzo ColittiPerhaps this kernel is too old to support it.
1071eccad2f9baf2dc69e46d2ef5a6f2b6f928e185bLorenzo ColittiYou may get asked lots of questions.
1081eccad2f9baf2dc69e46d2ef5a6f2b6f928e185bLorenzo ColittiKeep enter pressed to accept the defaults.
1091eccad2f9baf2dc69e46d2ef5a6f2b6f928e185bLorenzo Colitti
1101eccad2f9baf2dc69e46d2ef5a6f2b6f928e185bLorenzo ColittiEOF
111a9fe6b7c67383ea81aa8cbed9928dff4a517d944Lorenzo Colitti  fi
112a9fe6b7c67383ea81aa8cbed9928dff4a517d944Lorenzo Colitti
113a9fe6b7c67383ea81aa8cbed9928dff4a517d944Lorenzo Colitti  # Compile the kernel.
114a9fe6b7c67383ea81aa8cbed9928dff4a517d944Lorenzo Colitti  make -j32 linux ARCH=um SUBARCH=x86_64 CROSS_COMPILE=
115a9fe6b7c67383ea81aa8cbed9928dff4a517d944Lorenzo Colitti  KERNEL_BINARY=./linux
1161eccad2f9baf2dc69e46d2ef5a6f2b6f928e185bLorenzo Colittifi
1176ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo Colitti
1186ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo Colitti
1196ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo Colitti# Get the absolute path to the test file that's being run.
1206ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo Colittidir=/host$(dirname $(readlink -f $0))
1216ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo Colitti
1226ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo Colitti# Start the VM.
123a9fe6b7c67383ea81aa8cbed9928dff4a517d944Lorenzo Colittiexec $KERNEL_BINARY umid=net_test ubda=$(dirname $0)/$ROOTFS \
1246ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo Colitti    mem=512M init=/sbin/net_test.sh net_test=$dir/$test \
1256ef3e4fdfd823b08aca5ea2c2368e956b5e0eaeaLorenzo Colitti    $netconfig
126