5 # Linux bridge for connecting lan and wan network of guest machines
6 BR_LAN="${BR_LAN:-br-lan}"
7 BR_WAN="${BR_WAN:-br-wan}"
9 # Host network interface providing internet access for guest machines
10 IF_INET="${IF_INET:-eth0}"
12 # qemu-bridge-helper does two things here
14 # - create tap interface
15 # - add the tap interface to bridge
17 # as such it requires CAP_NET_ADMIN to do its job. It will be convenient to
18 # have it as a root setuid program. Be aware of the security risks implied
20 # the helper has an acl list which defaults to deny all bridge. we need to add
21 # $BR_LAN and $BR_WAN to its allow list
23 # # sudo vim /etc/qemu/bridge.conf
27 # Other allowed directives can be 'allow all', 'deny all', 'include xxx', See
28 # qemu-bridge-helper.c of qemu source code for details.
30 # The helper can be provided by package qemu-system-common on debian, or
31 # qemu-kvm-common on rhel
33 HELPER="${HELPER:-/usr/libexec/qemu-bridge-helper}"
35 ### end of global settings
42 # setup bridge for LAN network
43 sudo ip link add dev "$BR_LAN" type bridge
44 sudo ip link set dev "$BR_LAN" up
45 sudo ip addr add 192.168.1.3/24 dev "$BR_LAN"
47 # setup bridge for WAN network
49 # minimal dnsmasq config for configuring guest wan network with dhcp
51 # # sudo apt-get install dnsmasq
52 # # sudo vi /etc/dnsmasq.conf
54 # dhcp-range=192.168.7.50,192.168.7.150,255.255.255.0,30m
56 sudo ip link add dev "$BR_WAN" type bridge
57 sudo ip link set dev "$BR_WAN" up
58 sudo ip addr add 192.168.7.1/24 dev "$BR_WAN"
60 # guest internet access
61 sudo sysctl -w "net.ipv4.ip_forward=1"
62 sudo sysctl -w "net.ipv4.conf.$BR_WAN.proxy_arp=1"
63 while sudo iptables -t nat -D POSTROUTING -o "$IF_INET" -j MASQUERADE 2>/dev/null; do true; done
64 sudo iptables -t nat -A POSTROUTING -o "$IF_INET" -j MASQUERADE
68 ip link show "$BR_LAN" >/dev/null || return 1
69 ip link show "$BR_WAN" >/dev/null || return 1
71 __errmsg "helper $HELPER is not an executable"
78 __errmsg "please check the script content to see the environment requirement"
82 #do_setup; check_setup; exit $?
86 Usage: $SELF [-h|--help]
88 [<subtarget> [<extra-qemu-options>]]
92 <subtarget> will default to "generic" and must be specified if
93 <extra-qemu-options> are present
95 e.g. <subtarget> for malta can be le, be, le64, be64, le-glibc, le64-glibc, etc
97 <kernel>, <rootfs> can be required or optional arguments to qemu depending on
98 the actual <target> in use. They will default to files under bin/targets/
103 $SELF x86 64 -enable-kvm -device virtio-balloon-pci
104 $SELF x86 64 -incoming tcp:0:4444
110 --kernel bin/targets/armvirt/32/lede-armvirt-32-zImage \\
111 --rootfs bin/targets/armvirt/32/lede-armvirt-32-root.ext4
116 hexdump -n 3 -e '"52:54:00:" 2/1 "%02x:" 1/1 "%02x"' /dev/urandom
120 while [ "$#" -gt 0 ]; do
122 --kernel) o_kernel="$2"; shift 2 ;;
123 --rootfs) o_rootfs="$2"; shift 2 ;;
129 if [ -z "$o_target" ]; then
131 elif [ -z "$o_subtarget" ]; then
134 o_qemu_extra=("${o_qemu_extra[@]}" "$1")
141 MAC_LAN="$(rand_mac)"
142 MAC_WAN="$(rand_mac)"
143 [ -n "$o_target" ] || {
147 [ -n "$o_subtarget" ] || o_subtarget="generic"
148 o_bindir="bin/targets/$o_target/$o_subtarget"
151 start_qemu_armvirt() {
152 local kernel="$o_kernel"
153 local rootfs="$o_rootfs"
157 case "${o_subtarget%-*}" in
159 qemu_exe="qemu-system-arm"
161 [ -n "$kernel" ] || kernel="$o_bindir/lede-$o_target-${o_subtarget%-*}-zImage-initramfs"
164 qemu_exe="qemu-system-aarch64"
166 [ -n "$kernel" ] || kernel="$o_bindir/lede-$o_target-${o_subtarget%-*}-Image-initramfs"
169 __errmsg "target $o_target: unknown subtarget $o_subtarget"
173 [ -z "$rootfs" ] || {
174 if [ ! -f "$rootfs" -a -s "$rootfs.gz" ]; then
178 "-drive" "file=$rootfs,format=raw,if=virtio" \
179 "-append" "root=/dev/vda rootwait" \
180 "${o_qemu_extra[@]}" \
184 "$qemu_exe" -machine virt -cpu "$cpu" -nographic \
185 -netdev bridge,id=lan,br="$BR_LAN,helper=$HELPER" -device virtio-net-pci,id=devlan,netdev=lan,mac="$MAC_LAN" \
186 -netdev bridge,id=wan,br="$BR_WAN,helper=$HELPER" -device virtio-net-pci,id=devwan,netdev=wan,mac="$MAC_WAN" \
195 local kernel="$o_kernel"
197 # o_subtarget can be le, be, le64, be64, le-glibc, le64-glibc, etc..
198 is64="$(echo $o_subtarget | grep -o 64)"
199 [ "$(echo "$o_subtarget" | grep -o '^..')" = "le" ] && isel="el"
200 qemu_exe="qemu-system-mips$is64$isel"
202 [ -n "$kernel" ] || kernel="$o_bindir/lede-malta-${o_subtarget%-*}-vmlinux-initramfs.elf"
204 # NOTE: order of wan, lan -device arguments matters as it will affect which
205 # one will be actually used as the wan, lan network interface inside the
207 "$qemu_exe" -machine malta -nographic \
208 -netdev bridge,id=wan,br="$BR_WAN,helper=$HELPER" -device pcnet,netdev=wan,mac="$MAC_WAN" \
209 -netdev bridge,id=lan,br="$BR_LAN,helper=$HELPER" -device pcnet,netdev=lan,mac="$MAC_LAN" \
215 local rootfs="$o_rootfs"
218 [ -n "$rootfs" ] || {
219 rootfs="$o_bindir/lede-$o_target-${o_subtarget%-*}-combined-ext4.img"
220 if [ ! -f "$rootfs" -a -s "$rootfs.gz" ]; then
225 # generic: 32-bit, pentium4 (CONFIG_MPENTIUM4), kvm guest, virtio
226 # legacy: 32-bit, i486 (CONFIG_M486)
227 # 64: 64-bit, kvm guest, virtio
229 case "${o_subtarget%-*}" in
230 legacy) qemu_exe="qemu-system-i386" ;;
231 generic|64) qemu_exe="qemu-system-x86_64" ;;
233 __errmsg "target $o_target: unknown subtarget $o_subtarget"
238 case "${o_subtarget%-*}" in
240 # use IDE (PATA) disk instead of AHCI (SATA). Refer to link
241 # [1] for related discussions
243 # To use AHCI interface
245 # -device ich9-ahci,id=ahci \
246 # -device ide-drive,drive=drv0,bus=ahci.0 \
247 # -drive "file=$rootfs,format=raw,id=drv0,if=none" \
249 # [1] https://dev.openwrt.org/ticket/17947
250 "$qemu_exe" -nographic \
251 -netdev bridge,id=lan,br="$BR_LAN,helper=$HELPER" -device e1000,id=devlan,netdev=lan,mac="$MAC_LAN" \
252 -netdev bridge,id=wan,br="$BR_WAN,helper=$HELPER" -device e1000,id=devwan,netdev=wan,mac="$MAC_WAN" \
253 -device ide-drive,drive=drv0 \
254 -drive "file=$rootfs,format=raw,id=drv0,if=none" \
258 "$qemu_exe" -nographic \
259 -netdev bridge,id=lan,br="$BR_LAN,helper=$HELPER" -device virtio-net-pci,id=devlan,netdev=lan,mac="$MAC_LAN" \
260 -netdev bridge,id=wan,br="$BR_WAN,helper=$HELPER" -device virtio-net-pci,id=devwan,netdev=wan,mac="$MAC_WAN" \
261 -drive "file=$rootfs,format=raw,if=virtio" \
269 armvirt) start_qemu_armvirt ;;
270 malta) start_qemu_malta ;;
271 x86) start_qemu_x86 ;;
273 __errmsg "target $o_target is not supported yet"