mirror of
https://git.yoctoproject.org/meta-arm
synced 2026-06-07 03:04:27 +00:00
arm-autonomy/xenguest-network: Add private network support for xenguest
Introduce the private/internal network support for xenguest by using NAT and applying the proper iptables rules to allow the guest to have access to the external network. The XENGUEST_NETWORK_TYPE variable was introduced to allow the user to setup the xenguest network type between "bridge" (default), "nat" and "none". Change-Id: I919e5b0fd0809093698b9dec3a9503b598b54828 Issue-Id: SCM-1019 Signed-off-by: Diego Sueiro <diego.sueiro@arm.com> Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com> Signed-off-by: Jon Mason <jon.mason@arm.com>
This commit is contained in:
@@ -58,10 +58,14 @@ XENGUEST_IMAGE_DISK_SIZE ??= "${@ '4' if not d.getVar('INITRAMFS_IMAGE') else '0
|
||||
# and containing the root filesystem produced by Yocto
|
||||
XENGUEST_IMAGE_DISK_PARTITIONS ??= "1:${XENGUEST_IMAGE_DISK_SIZE}:ext4:rootfs.tar.gz"
|
||||
|
||||
# XENGUEST_IMAGE_NETWORK_BRIDGE can be set to 1 to have a network interface
|
||||
# on the guest connected to host bridged network. This will provide the guest
|
||||
# with a network interface connected directly to the external network
|
||||
XENGUEST_IMAGE_NETWORK_BRIDGE ??= "1"
|
||||
# XENGUEST_IMAGE_NETWORK_TYPE can be set to "bridge", "nat" or "none".
|
||||
# The "bridge" type will share the physical eth interface from dom0 with the
|
||||
# domU. This will allow the domU to have access to the external network.
|
||||
# The "nat" type will setup a virtual network between dom0 and domU and also
|
||||
# configure and run the dhcpd on dom0 to serve the domU.
|
||||
# The "none" type will not affect any networking setting between on dom0 and
|
||||
# domU.
|
||||
XENGUEST_IMAGE_NETWORK_TYPE ??= "bridge"
|
||||
|
||||
# Sub-directory in wich the guest is created. This is create in deploy as a
|
||||
# subdirectory and must be coherent between all components using this class so
|
||||
@@ -147,10 +151,10 @@ xenguest_image_create() {
|
||||
call_xenguest_mkimage update --set-param=GUEST_AUTOBOOT=0
|
||||
fi
|
||||
|
||||
if [ "${XENGUEST_IMAGE_NETWORK_BRIDGE}" = "1" ]; then
|
||||
call_xenguest_mkimage update --set-param=NETWORK_BRIDGE=1
|
||||
if [ -n "${XENGUEST_IMAGE_NETWORK_TYPE}" ]; then
|
||||
call_xenguest_mkimage update --set-param=XENGUEST_NETWORK_TYPE="${XENGUEST_IMAGE_NETWORK_TYPE}"
|
||||
else
|
||||
call_xenguest_mkimage update --set-param=NETWORK_BRIDGE=0
|
||||
call_xenguest_mkimage update --set-param=XENGUEST_NETWORK_TYPE="none"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
xenguest network bridge
|
||||
=======================
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
xenguest-network-bridge is creating a network bridge to allow some guests to
|
||||
have a direct connection to the external network.
|
||||
To do this, a bridge is created on the host using brctl with the network
|
||||
interfaces added to it so that the bridge is connected to the external network.
|
||||
It is also adding a guest init script which will, for guests configured to use
|
||||
it, create a virtual network interface for the guest and connect it to the
|
||||
network bridge on the host.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
On the host the package xenguest-network-bridge must be included in your image.
|
||||
|
||||
On the xenguest image of your guest, the parameter NETWORK_BRIDGE must be set
|
||||
to 1 (using xenguest-mkimage --set-param=NETWORK_BRIDGE=1).
|
||||
|
||||
Bitbake parameters
|
||||
------------------
|
||||
Several parameters are available to configure the xenguest network bridge
|
||||
during Yocto project compilation (those can be set in your project local.conf,
|
||||
for example).
|
||||
|
||||
The following parameters are available:
|
||||
|
||||
- XENGUEST_NETWORK_BRIDGE_NAME: This variable defines the name of the network
|
||||
bridge that is created on the host during init.
|
||||
This is set by default to "xenbr0".
|
||||
|
||||
- XENGUEST_NETWORK_BRIDGE_MEMBERS: This variable defines the list of network
|
||||
interfaces that are added to the bridge when it is created on the host during
|
||||
init.
|
||||
This is set by default to "eth0".
|
||||
|
||||
- XENGUEST_NETWORK_BRIDGE_CONFIG: This variable defines the configuration file
|
||||
to use to configure the bridge network. By default it points to have file
|
||||
configuring the network using dhcp.
|
||||
You can provide a different file using a bbappend and make this variable
|
||||
point to it if you want to customize your network configuration.
|
||||
|
||||
- XENGUEST_IMAGE_NETWORK_BRIDGE: This variable can be set to 0 or 1 on guest
|
||||
projects to enable or not the connection of the guest to the host bridge.
|
||||
This is set by default to "1".
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
Xenguest Network
|
||||
================
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
The xenguest-network package is primarly creating a network bridge to share
|
||||
the host eth physical interfaces with the guests virtual interfaces (vif).
|
||||
This way the guests can have access to the external network.
|
||||
|
||||
At the moment 3 types of network arrangements are provided:
|
||||
|
||||
- Bridge: where the guest vif is added to the created bridge interface;
|
||||
|
||||
- NAT: where a private subnet is created for the guest, a dhcpd is started on
|
||||
the host to serve the guest and the proper iptables rules are created to
|
||||
allow the guest to access the external network;
|
||||
|
||||
- None: the guest vif is not connected to the bridge.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
On the host project the package xenguest-network must be included in your
|
||||
image, and on the guest project the XENGUEST_NETWORK_TYPE needs to be set to
|
||||
"bridge", "nat" or "none".
|
||||
|
||||
Bitbake parameters
|
||||
------------------
|
||||
|
||||
Several parameters are available to configure the xenguest network bridge
|
||||
during Yocto project compilation (those can be set in your project local.conf
|
||||
or xenguest-network.bbappend, for example).
|
||||
|
||||
The following parameters are available:
|
||||
|
||||
- XENGUEST_NETWORK_BRIDGE_NAME: This variable defines the name of the network
|
||||
bridge that is created on the host during init.
|
||||
This is set by default to "xenbr0".
|
||||
|
||||
- XENGUEST_NETWORK_BRIDGE_MEMBERS: This variable defines the list of the
|
||||
physical network interfaces that are added to the bridge when it is created
|
||||
on the host during init.
|
||||
By default no physical interfaces are added.
|
||||
|
||||
- XENGUEST_NETWORK_BRIDGE_CONFIG: This variable defines the configuration file
|
||||
to use to configure the bridge network. By default it points to have file
|
||||
configuring the network using dhcp.
|
||||
You can provide a different file using a bbappend and make this variable
|
||||
point to it if you want to customize your network configuration.
|
||||
|
||||
- XENGUEST_IMAGE_NETWORK_TYPE: This variable can be set to "bridge" (default),
|
||||
"nat" or "none".
|
||||
The **bridge** type will add the domU vif interface to a bridge which also
|
||||
contains the dom0 physical interface giving the guest direct access to the
|
||||
external network.
|
||||
The **nat** type will setup a private network between dom0 and domU, setup
|
||||
the appropriate routing table, configure and run the dhcpd on dom0 to serve
|
||||
the domU and apply the iptables rules to allow the guest to acess the
|
||||
external network. The dhcpd configuration for the guest can be customised by
|
||||
replacing the
|
||||
"meta-arm-autonomy/recipes-extended/xenguest/files/dhcpd-params.cfg" file
|
||||
in a xenguest-network.bbappend. The dhcpd-params.cfg file is installed in
|
||||
the xenguest image and copied to
|
||||
"/etc/xenguest/guests/${guestname}/files/dhcpd-params.cfg" when the guest
|
||||
image is created. It will be consumed by the
|
||||
"/etc/xen/scripts/vif-post.d/00-vif-xenguest.hook" script which is called by
|
||||
"/etc/xen/scripts/vif-nat" script when starting/stopping the xenguest.
|
||||
The **none** type will not affect any networking setting between on dom0 and
|
||||
domU.
|
||||
@@ -41,7 +41,7 @@ IMAGE_INSTALL += " \
|
||||
packagegroup-core-ssh-openssh \
|
||||
qemu-system-i386 \
|
||||
xenguest-manager \
|
||||
xenguest-network-bridge \
|
||||
xenguest-network \
|
||||
"
|
||||
|
||||
# Build xen binary
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
#============================================================================
|
||||
# ${XEN_SCRIPT_DIR}/vif-post.d/00-vif-xenguest.hook
|
||||
#
|
||||
# Script for performing local configuration of a vif.
|
||||
# This script will be sourced by, e.g., vif-bridge after the hotplugging
|
||||
# system calls vif-bridge. The script is here and not simply executed as
|
||||
# a udev rule because this allows simple access to several environment
|
||||
# variables set by the calling vif-* script.
|
||||
#
|
||||
# Environment vars:
|
||||
# command (add|remove|online|offline)
|
||||
# dev vif interface name (required).
|
||||
# main_ip IP address of Dom0
|
||||
# ip list of IP networks for the vif, space-separated
|
||||
# XENBUS_PATH path to this device's details in the XenStore (required).
|
||||
#============================================================================
|
||||
|
||||
domid=$(xenstore_read "${XENBUS_PATH}/frontend-id")
|
||||
guestname=$(xenstore_read "/local/domain/${domid}/name")
|
||||
bridge=$(xenstore_read "${XENBUS_PATH}/bridge")
|
||||
|
||||
if [ ! -f /etc/xenguest/guests/${guestname}/params.cfg ]; then
|
||||
log debug "No /etc/xenguest/guests/${guestname}/params.cfg. Exiting."
|
||||
return
|
||||
fi
|
||||
|
||||
# Source the params file to get the choosen XENGUEST_NETWORK_TYPE
|
||||
. /etc/xenguest/guests/${guestname}/params.cfg
|
||||
|
||||
# We need to get the xenguest subnet prefix to set the subnet and
|
||||
# the fixed ip to assing to the guest.
|
||||
get_subnet_prefix() {
|
||||
# ${vif_ip} is set in the vif-nat script
|
||||
echo ${vif_ip} | awk -F. '{print $1"."$2"."$3}'
|
||||
}
|
||||
|
||||
subnetprefix=$(get_subnet_prefix)
|
||||
|
||||
dhcpd_remove_conf_entry()
|
||||
{
|
||||
local tmpfile=$(mktemp)
|
||||
|
||||
# Remove the the xenguest dhcpd config file inclusion in the dhcpd
|
||||
# main config
|
||||
grep -v "include \"${XENGUEST_DHCPD_CONF_FILE}\";" \
|
||||
"${dhcpd_conf_file}" >"${tmpfile}"
|
||||
if ! diff "${tmpfile}" "${dhcpd_conf_file}" >/dev/null
|
||||
then
|
||||
cp "${tmpfile}" "${dhcpd_conf_file}"
|
||||
fi
|
||||
rm ${tmpfile}
|
||||
|
||||
# Remove the generated the xenguest dhcpd file
|
||||
rm ${XENGUEST_DHCPD_CONF_FILE}
|
||||
}
|
||||
|
||||
# This function removes the dhcpd options added by the vif-nat script and
|
||||
# adds the user provided options under the ${XENGUEST_DHCPD_HOST_OPTIONS}
|
||||
# variable set in "/etc/xenguest/guests/${guestname}/files/dhcpd-params.cfg"
|
||||
# file.
|
||||
dhcpd_add_conf_entries()
|
||||
{
|
||||
# We need to remove the previous added entry from vif-nat script
|
||||
dhcp_remove_entry
|
||||
|
||||
# Include the xenguest dhcpd config file in the dhcpd main config
|
||||
echo >>"${dhcpd_conf_file}" "include \"${XENGUEST_DHCPD_CONF_FILE}\";"
|
||||
|
||||
# Generate the xenguest dhcpd file
|
||||
echo -e "$(eval "echo -e \"$(cat ${XENGUEST_DHCPD_PARAMS_FILE})\"")" \
|
||||
>> "${XENGUEST_DHCPD_CONF_FILE}"
|
||||
|
||||
# Re-add the dhcpargs entries removed by dhcp_remove_entry call
|
||||
dhcparg_add_entry
|
||||
}
|
||||
|
||||
dhcpd_online(){
|
||||
log debug "dhcpd_online"
|
||||
claim_lock "vif-nat-dhcp"
|
||||
dhcpd_add_conf_entries
|
||||
release_lock "vif-nat-dhcp"
|
||||
"$dhcpd_init_file" restart || true
|
||||
}
|
||||
|
||||
dhcpd_offline(){
|
||||
log debug "dhcpd_offline"
|
||||
claim_lock "vif-nat-dhcp"
|
||||
dhcpd_remove_conf_entry
|
||||
release_lock "vif-nat-dhcp"
|
||||
"$dhcpd_init_file" restart || true # We need to ignore failure because
|
||||
# ISC dhcpd 3 borks if there is nothing
|
||||
# for it to do, which is the case if
|
||||
# the outgoing interface is not
|
||||
# configured to offer leases and there
|
||||
# are no vifs.
|
||||
}
|
||||
|
||||
case "${XENGUEST_NETWORK_TYPE}" in
|
||||
nat)
|
||||
XENGUEST_DHCPD_PARAMS_FILE=${XENGUEST_DHCPD_PARAMS_FILE:-"/etc/xenguest/guests/${guestname}/files/dhcpd-params.cfg"}
|
||||
if [ ! -f ${XENGUEST_DHCPD_PARAMS_FILE} ]; then
|
||||
log debug "No ${XENGUEST_DHCPD_PARAMS_FILE} file. Aborting"
|
||||
return
|
||||
fi
|
||||
|
||||
XENGUEST_DHCPD_CONF_FILE="/etc/dhcp/dhcpd.dom$domid.conf"
|
||||
|
||||
case "$command" in
|
||||
online)
|
||||
dhcpd_online
|
||||
|
||||
# Enable ip forwarding and NAT for the ${bridge} interface
|
||||
sysctl -w net.ipv4.ip_forward=1
|
||||
iptables_w -t nat -A POSTROUTING -o ${bridge} -j MASQUERADE -m comment --comment "dom${domid}"
|
||||
;;
|
||||
offline)
|
||||
dhcpd_offline
|
||||
|
||||
# Remove the NAT iptables rules created for the dom${domid}
|
||||
guest_ipt_rule=$(iptables_w -t nat -vL POSTROUTING -n --line-number | grep -w dom${domid} | awk '{print $1}' | tac)
|
||||
for rule in ${guest_ipt_rule}; do iptables_w -t nat --delete POSTROUTING ${rule}; done
|
||||
|
||||
# If there is no more NAT iptables rules we disable ip forwarding
|
||||
ipt_nat_rules=$(iptables_w -t nat -vL POSTROUTING -n --line-number | grep MASQUERADE | awk '{print $1}')
|
||||
[ -z "${ipt_nat_rules##*[!0-9]*}" ] && sysctl -w net.ipv4.ip_forward=0
|
||||
;;
|
||||
esac
|
||||
|
||||
;;
|
||||
esac
|
||||
@@ -0,0 +1,30 @@
|
||||
# This file holds the guest dhcpd options running on Dom0.
|
||||
# The "/etc/xen/scripts/vif-post.d/00-vif-xenguest.hook" called in the end of
|
||||
# the vif-nat script will use this file to generate the final dhcpd
|
||||
# configuration.
|
||||
|
||||
# This file is added in the xenguest image and installed in dom0 under
|
||||
# /etc/xenguest/guests/${guestname}/files/dhcpd-params.cfg when the guest
|
||||
# image is created.
|
||||
# Any customizations to it should be performed by replacing it via a bbappend.
|
||||
|
||||
# The \${hostname}, \${mac}, \${vif_ip} and \${router_ip} variables are set in
|
||||
# the vif-nat script context. The \${subnetprefix} variable is set in the
|
||||
# 00-vif-xenguest.hook script context.
|
||||
|
||||
# The "subnet" configuration node is mandatory in order to have the dhcpd
|
||||
# properly running.
|
||||
|
||||
host ${hostname} {
|
||||
hardware ethernet ${mac};
|
||||
fixed-address ${vif_ip};
|
||||
option routers ${router_ip};
|
||||
option subnet-mask 255.255.255.0;
|
||||
option broadcast-address ${subnetprefix}.255;
|
||||
option domain-name-servers 8.8.8.8;
|
||||
option host-name \"${hostname}\";
|
||||
option domain-name \"example.com\";
|
||||
}
|
||||
|
||||
subnet ${subnetprefix}.0 netmask 255.255.255.0 {
|
||||
}
|
||||
@@ -9,7 +9,24 @@ BRIDGE_NAME="###BRIDGE_NAME###"
|
||||
# get guest parameters
|
||||
. ./params.cfg
|
||||
|
||||
if [ "${NETWORK_BRIDGE:-}" = "1" ]; then
|
||||
echo "vif = ['${BRIDGE_NAME}']" >> ${guestname}.cfg
|
||||
fi
|
||||
|
||||
case "${XENGUEST_NETWORK_TYPE:-}" in
|
||||
nat)
|
||||
# Create the symlinks for the files that vif-nat script expects
|
||||
if [ ! -f /etc/dhcpd.conf ]; then
|
||||
ln -s dhcp/dhcpd.conf /etc/dhcpd.conf
|
||||
fi
|
||||
if [ ! -f /etc/init.d/dhcp3-server ]; then
|
||||
ln -s dhcp-server /etc/init.d/dhcp3-server
|
||||
fi
|
||||
if [ ! -f /etc/default/dhcp3-server ]; then
|
||||
ln -s dhcp-server /etc/default/dhcp3-server
|
||||
fi
|
||||
echo "vif = ['script=vif-nat']" >> ${guestname}.cfg
|
||||
;;
|
||||
bridge)
|
||||
echo "vif = ['script=vif-bridge,bridge=${BRIDGE_NAME}']" >> ${guestname}.cfg
|
||||
;;
|
||||
*)
|
||||
echo "${@}: XENGUEST_NETWORK_TYPE=$XENGUEST_NETWORK_TYPE invalid"
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -35,7 +35,12 @@ LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda
|
||||
XENGUEST_IMAGE_SRC_URI_DISK_FILES ??= ""
|
||||
|
||||
# Add xen files
|
||||
XENGUEST_IMAGE_SRC_URI_XEN_FILES ??= ""
|
||||
# Any extrafiles files to be added to XENGUEST_IMAGE_SRC_URI_XEN_FILES should
|
||||
# be performed via XENGUEST_IMAGE_SRC_URI_XEN_FILES_append.
|
||||
# The dhcpd-params.cfg holds the dhcpd configuration for Dom0. And it is used
|
||||
# when XENGUEST_IMAGE_NETWORK_TYPE="nat". Any customizations to it should be
|
||||
# performed by replacing it via a xenguest-network.bbappend.
|
||||
XENGUEST_IMAGE_SRC_URI_XEN_FILES = "file://dhcpd-params.cfg"
|
||||
|
||||
# Add xen configuration elements
|
||||
XENGUEST_IMAGE_SRC_URI_XEN_CONFIG ??= ""
|
||||
|
||||
+14
-2
@@ -1,5 +1,5 @@
|
||||
# Recipe to handle xenguest network configuration
|
||||
DESCRIPTION = "XenGuest Network Bridge"
|
||||
DESCRIPTION = "Xenguest Network"
|
||||
|
||||
LICENSE = "MIT"
|
||||
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
|
||||
@@ -20,6 +20,7 @@ SRC_URI = " \
|
||||
file://xenguest-network-bridge.in \
|
||||
file://xenguest-network-bridge-dhcp.cfg.in \
|
||||
file://network-bridge.sh.in \
|
||||
file://00-vif-xenguest.hook \
|
||||
"
|
||||
|
||||
# Bridge configurator needs to run before S01networking init script
|
||||
@@ -49,8 +50,19 @@ do_install() {
|
||||
install -d -m 755 ${D}${sysconfdir}/xenguest/init.pre
|
||||
install -m 755 ${WORKDIR}/network-bridge.sh \
|
||||
${D}${sysconfdir}/xenguest/init.pre/.
|
||||
|
||||
install -d ${D}${sysconfdir}/xen/scripts/vif-post.d
|
||||
install -m 755 ${WORKDIR}/00-vif-xenguest.hook \
|
||||
${D}${sysconfdir}/xen/scripts/vif-post.d/.
|
||||
}
|
||||
|
||||
RDEPENDS_${PN} += "bridge-utils"
|
||||
RDEPENDS_${PN} += "bridge-utils \
|
||||
iptables \
|
||||
dhcp-server \
|
||||
kernel-module-xt-tcpudp \
|
||||
kernel-module-xt-physdev \
|
||||
kernel-module-xt-comment \
|
||||
"
|
||||
FILES_${PN} += "${sysconfdir}/network/interfaces.d/xenguest-network-bridge.cfg"
|
||||
FILES_${PN} += "${sysconfdir}/xenguest/init.pre/network-bridge.sh"
|
||||
FILES_${PN} += "${sysconfdir}/xen/scripts/vif-post.d/00-vif-xenguest.hook"
|
||||
Reference in New Issue
Block a user