Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Run OpenWrt on QEMU virtual machines with LAN and WAN network.
#
# The following script will
# - Create Linux bridge $BR_WAN, $BR_LAN
# - Install IP addresses and basic routes
# - Enable proxy_arp on $BR_WAN
# - Enable ip_forward
# - Enable MASQUERADE on $IF_INET
# - $BR_LAN, $BR_WAN has to be allowed in ~/.usr/etc/qemu/bridge.conf
#
# Sample content:
#
# allow br-lan
# allow br-wan
#
# See qemu-bridge-helper.c of QEMU source code for details (`allow all`, `deny all`, `include xxx` can also be used).
#
# config variables
BR_WAN="br-wan"
BR_LAN="br-lan"
IF_INET="eth0"
# - qemu-bridge-help has to be root setuid program.
HELPER="$HOME/.usr/libexec/qemu-bridge-helper"
mac_rand() {
hexdump -n 3 -e '"52:54:00:" 2/1 "%02x:" 1/1 "%02x"' /dev/urandom
}
# setup bridge for LAN network
sudo ip link add dev "$BR_LAN" type bridge
sudo ip link set dev "$BR_LAN" up
sudo ip addr add 192.168.1.3 dev "$BR_LAN"
sudo ip route add 192.168.1.0/24 dev "$BR_LAN"
# setup bridge for WAN network
sudo ip link add dev "$BR_WAN" type bridge
sudo ip addr add 192.168.7.1 dev "$BR_WAN"
sudo ip link set dev "$BR_WAN" up
#sudo ip link set dev tap0 master "$BR_WAN"
sudo ip route add 192.168.7.0/24 dev "$BR_WAN"
# Internet access setup
sudo sysctl -w net.ipv4.ip_forward=1
sudo sysctl -w net.ipv4.conf."$BR_WAN".proxy_arp=1
sudo iptables -t nat -A POSTROUTING -o "$IF_INET" -j MASQUERADE
openwrt_wan_static() {
# Run this within OpenWrt
uci batch <<EOF
delete network.wan
set network.wan=interface
set network.wan.ifname=eth1
set network.wan.proto=static
set network.wan.ipaddr=192.168.7.2
set network.wan.netmask=255.255.255.0
set network.wan.gateway=192.168.7.1
add_list network.wan.dns=208.67.222.222
add_list network.wan.dns=208.67.220.220
commit
EOF
/etc/init.d/network reload
}
host_dnsmasq_br_wan() {
# Run this within host machine
#
#sudo apt-get install dnsmasq
#sudo vi /etc/dnsmasq.conf
#
# Minimal conf. The netmask is needed as br-wan is a bridge otherwise dnsmasq would complain "no address range available for DHCP request via br-wan"
#
# interface=br-wan
# dhcp-range=192.168.7.50,192.168.7.150,255.255.255.0,30m
}
MAC_LAN="$(mac_rand)"
MAC_WAN="$(mac_rand)"
qemu-system-mipsel -M malta -kernel bin/malta/openwrt-malta-le-vmlinux-initramfs.elf -nographic -m 128 \
-netdev bridge,id=wan,br="$BR_WAN,helper=$HELPER" -device pcnet,netdev=wan,mac="$MAC_WAN" \
-netdev bridge,id=lan,br="$BR_LAN,helper=$HELPER" -device pcnet,netdev=lan,mac="$MAC_LAN"
# TODO
#
# 1. Network device
# 2. How to get a EL-flavour arm
# 3. How to get ARMv7
#
MAC_LAN="$(mac_rand)"
MAC_WAN="$(mac_rand)"
IMG=bin/realview/openwrt-realview-vmlinux-initramfs.elf
qemu-system-arm -M realview-eb-mpcore -nographic -m 128 \
-kernel "$IMG"
# SATA and IDE interface? https://dev.openwrt.org/ticket/17947
#
# This should work for both subtargets 64 and generic
MAC_LAN="$(mac_rand)"
MAC_WAN="$(mac_rand)"
IMG=bin/x86/openwrt-x86-64-combined-ext4.img
if [ ! -s "$IMG" -a -s "$IMG.gz" ]; then
zcat "$IMG.gz" >"$IMG"
fi
package/system/procd/files/hotplug.json
qemu-system-x86_64 -nographic -m 128 \
-netdev bridge,id=lan,br="$BR_LAN,helper=$HELPER" -device e1000,netdev=lan,mac="$MAC_LAN" \
-netdev bridge,id=wan,br="$BR_WAN,helper=$HELPER" -device e1000,netdev=wan,mac="$MAC_WAN" \
-device ich9-ahci,id=ahci \
-device ide-drive,drive=drv0,bus=ahci.0 \
-drive "file=$IMG,format=raw,id=drv0,if=none" \
# 64,kvm_guest uses virtio drivers
#
# - List network information with `info network`
# - Delete device with `device_del devlan`
# - Delete network interface from host system (e.g. tap devices) with `netdev_del lan`
#
# Add/del actions operate by id and default id's like 'virtio-net-pci.0' won't work as per QEMU 2.3.0. See "qdev: Assign a default device ID when none is p" for details, https://lists.nongnu.org/archive/html/qemu-devel/2014-01/msg01013.html
#
# From Paolo Bonzini
# > Without the patch, how does a user unplug a device for which he didn't specify
# > an ID (eg. forgotten, added quickly...)
# He doesn't. :)
#
# OpenWrt kvm_guest image enables CONFIG_VIRTIO_BALLOON by default.
#
# - `-balloon` is an alias of `-device virtio-balloon-pci`
# - a guest kernel thread `[vballoon]` is responsible for the interaction
# - `info balloon` to see the current actual memory reserved
# - `balloon 32` to resize the memory to 32MB
# - `ballone 65` will only resize the memory to 64MB
#
# - QEMU Internals: vhost architecture, http://blog.vmsplice.net/2011/09/qemu-internals-vhost-architecture.html
# - VIRTIO AND VHOST_NET, https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Virtualization_Tuning_and_Optimization_Guide/sect-Virtualization_Tuning_Optimization_Guide-Networking-Virtio_and_vhostnet.html
MAC_LAN="$(mac_rand)"
MAC_WAN="$(mac_rand)"
#IMG=bin/x86/openwrt-x86-kvm_guest-combined-ext4.img
IMG=bin/x86/openwrt-x86-64-combined-ext4.img
if [ ! -s "$IMG" -a -s "$IMG.gz" ]; then
zcat "$IMG.gz" >"$IMG"
fi
qemu-system-x86_64 -nographic -m 64 \
-netdev bridge,id=lan,br="$BR_LAN,helper=$HELPER" -device virtio-net-pci,id=devlan,netdev=lan,mac="$MAC_LAN" \
-netdev bridge,id=wan,br="$BR_WAN,helper=$HELPER" -device virtio-net-pci,id=devwan,netdev=wan,mac="$MAC_WAN" \
-drive "file=$IMG,format=raw,if=virtio" \
-device virtio-balloon-pci \
-chardev socket,path=/tmp/qga.sock,server,nowait,id=qga0 \
-device virtio-serial \
-device virtserialport,chardev=qga0,name=org.qemu.guest_agent.0 \
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.