Skip to content

Instantly share code, notes, and snippets.

@mmoya
Created May 17, 2012 18:39
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save mmoya/2720823 to your computer and use it in GitHub Desktop.
vif-bridge with ebtables
#!/bin/bash
#============================================================================
# ${XEN_SCRIPT_DIR}/vif-bridge
#
# Script for configuring a vif in bridged mode.
# The hotplugging system will call this script if it is specified either in
# the device configuration given to Xend, or the default Xend configuration
# in ${XEN_CONFIG_DIR}/xend-config.sxp. If the script is specified in
# neither of those places, then this script is the default.
#
# Usage:
# vif-bridge (add|remove|online|offline)
#
# Environment vars:
# vif vif interface name (required).
# XENBUS_PATH path to this device's details in the XenStore (required).
#
# Read from the store:
# bridge bridge to add the vif to (optional). Defaults to searching for the
# bridge itself.
# ip list of IP networks for the vif, space-separated (optional).
#
# up:
# Enslaves the vif interface to the bridge and adds iptables rules
# for its ip addresses (if any).
#
# down:
# Removes the vif interface from the bridge and removes the iptables
# rules for its ip addresses (if any).
#============================================================================
dir=$(dirname "$0")
. "$dir/vif-common.sh"
bridge=${bridge:-}
bridge=$(xenstore_read_default "$XENBUS_PATH/bridge" "$bridge")
if [ -z "$bridge" ]
then
bridge=$(brctl show | cut -d "" -f 2 | cut -f 1)
if [ -z "$bridge" ]
then
fatal "Could not find bridge, and none was specified"
fi
else
#
# Old style bridge setup with netloop, used to have a bridge name
# of xenbrX, enslaving pethX and vif0.X, and then configuring
# eth0.
#
# New style bridge setup does not use netloop, so the bridge name
# is ethX and the physical device is enslaved pethX
#
# So if...
#
# - User asks for xenbrX
# - AND xenbrX doesn't exist
# - AND there is a ethX device which is a bridge
#
# ..then we translate xenbrX to ethX
#
# This lets old config files work without modification
#
if [ ! -e "/sys/class/net/$bridge" ] && [ -z "${bridge##xenbr*}" ]
then
if [ -e "/sys/class/net/eth${bridge#xenbr}/bridge" ]
then
bridge="eth${bridge#xenbr}"
fi
fi
fi
RET=0
ip link show $bridge 1>/dev/null 2>&1 || RET=1
if [ "$RET" -eq 1 ]
then
fatal "Could not find bridge device $bridge"
fi
ebtlockfile="/var/lock/ebtables"
ebchain_out="${vif}_OUT"
ebchain_in="${vif}_IN"
ebtables="flock $ebtlockfile /sbin/ebtables"
case "$command" in
online)
setup_bridge_port "$vif"
add_to_bridge "$bridge" "$vif"
$ebtables -N "$ebchain_out" -P DROP
$ebtables -A FORWARD -o "$vif" -j "$ebchain_out"
$ebtables -A OUTPUT -o "$vif" -j "$ebchain_out"
$ebtables -N "$ebchain_in" -P DROP
$ebtables -A FORWARD -i "$vif" -j "$ebchain_in"
$ebtables -A INPUT -i "$vif" -j "$ebchain_in"
if [ ! -z "$ip" ]
then
mac=$(xenstore-read "$XENBUS_PATH/mac")
for oneip in $ip
do
$ebtables -A "$ebchain_out" -p ip4 -d "$mac" --ip-dst "$oneip" -j ACCEPT
$ebtables -A "$ebchain_out" -p arp --arp-ip-dst "$oneip" -j ACCEPT
$ebtables -A "$ebchain_in" -p ip4 -s "$mac" --ip-src "$oneip" -j ACCEPT
$ebtables -A "$ebchain_in" -p arp --arp-ip-src "$oneip" --arp-mac-src "$mac" -j ACCEPT
done
fi
;;
offline)
do_without_error brctl delif "$bridge" "$vif"
do_without_error ifconfig "$vif" down
$ebtables -D FORWARD -o "$vif" -j "$ebchain_out" || true
$ebtables -D OUTPUT -o "$vif" -j "$ebchain_out" || true
$ebtables -F "$ebchain_out" || true
$ebtables -X "$ebchain_out" || true
$ebtables -D FORWARD -i "$vif" -j "$ebchain_in" || true
$ebtables -D INPUT -i "$vif" -j "$ebchain_in" || true
$ebtables -F "$ebchain_in" || true
$ebtables -X "$ebchain_in" || true
;;
esac
log debug "Successful vif-bridge $command for $vif, bridge $bridge."
if [ "$command" == "online" ]
then
success
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment