-
-
Notifications
You must be signed in to change notification settings - Fork 12
/
qemu-hook
executable file
·76 lines (65 loc) · 2.89 KB
/
qemu-hook
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#!/bin/sh -e
#
# Libvirt qemu hook to magically connect VM bridge interfaces to desired untagged Vlan
#
# IF
# * the VM interface if configured to be connected to a bridge,
# * the bridge is configured to be vlan aware (vlan_filtering = 1)
# * the VM interface name ends with _vXXXX with XXXX being a one to four
# digit number
# the interface will be configured as an untagged port connected to vlan XXXX.
#
# See <man bridge> for more details about vlan aware bridges.
#
# Maximilian Wilhelm <[email protected]>
# -- Wed, 31 Aug 2016 20:48:02 +0200
my_name="qemu-magic"
# We only care for the "started" event.
if [ "$2" != 'started' ]; then
exit 0
fi
if ! which xmlstarlet >/dev/null 2>/dev/null; then
logger -t "${my_name}" "ERROR: xmlstarlet not found. Dying of shame."
echo "${my_name}: ERROR: xmlstarlet not found. Dying of shame." >&2
exit 1
fi
xmlstarlet sel -t -m '//interface[@type="bridge"]' -v 'concat(target/@dev, " ", source/@bridge)' --nl | while read iface bridge; do
if [ ! -d "/sys/class/net/${bridge}/bridge" ]; then
logger -t "${my_name}" "Bridge \"${bridge}\" for iface \"${iface}\" doesn't exist or isn't a bridge."
exit 2
fi
#
# Check if this kernel supports vlan-aware bridges and if ${bridge} is one
vlan_filtering=0
if [ -f "/sys/class/net/${bridge}/bridge/vlan_filtering" ]; then
vlan_filtering=$(cat "/sys/class/net/${bridge}/bridge/vlan_filtering")
fi
# If the interface is named *_vXXXX, with XXXX being a 1-4 digit number
# we assume that this iface should be connected to Vlan XXXX with
# an untagged port.
vlan_id=$(echo ${iface} | grep -o '_v[0-9]\{1,4\}$' | cut -c3-)
# If vlan filtering is activated and we found a vlan id, kindly do the needful.
if [ "${vlan_filtering}" -a "${vlan_id}" ]; then
# Remove association with vlan 1 and add association with
# vlan $vlan_id with packages being sent out untagged and
# untagged ingress packets get tagged accordingly.
bridge vlan del vid 1 dev "${iface}"
bridge vlan add vid "${vlan_id}" dev "${iface}" pvid untagged
logger -t "${my_name}" "Configured untagged pvid ${vlan_id} for ${iface} in bridge ${bridge}."
# If vlan filtering isn't activated or supported but we found a vlan id,
# this probably is an error!
elif [ ! "${vlan_filtering}" -a "${vlan_id}" ]; then
logger -t "${my_name}" -p user.error "ERROR: Should configure untagged pvid ${vlan_id} for ${iface} in bridge ${bridge}, but bridge does not support vlan filtering!"
fi
# We dont' care about "no vlan filtering AND no vlan id" as well as "vlan filtering AND no vlan id"
# If there is an configuration stanza in /etc/network/interfaces
# for this interfaces, we try to get it up and running. Proceed
# with fingers crossed.
if grep -q "^iface\s\+${iface}" /etc/network/interfaces; then
if ifup $iface; then
logger -t "${my_name}" "ifup'ed ${iface}."
else
logger -t "${my_name}" -p user.error "ifup ${iface} FAILED."
fi
fi
done