-
Notifications
You must be signed in to change notification settings - Fork 12
/
kerndev-qemu-tap-helper.sh
executable file
·163 lines (142 loc) · 3.38 KB
/
kerndev-qemu-tap-helper.sh
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#!/bin/bash
set -e; set -o pipefail
# Author: Jakub Klinkovský (Lahwaacz)
# https://github.com/lahwaacz
# Modified by Lorenzo Stoakes, with gratitude to Jakub's fine work!
########## Functions ##########
# Uncomment the following line to get debug output.
#DEBUG_OUTPUT=1
function say()
{
[[ -n "$DEBUG_OUTPUT" ]] && echo $@ || true
}
function error()
{
echo $@ >&2
}
## Check if a string represents a network interface
# $1: potential interface name
function is_interface()
{
[[ -d "/sys/class/net/$1" ]]
}
## Create new TAP interface
# $1: name of the interface to create
function create_tap()
{
if ! is_interface "$1"; then
say "Creating TAP interface '$1'"
ip tuntap add "$1" mode tap user "$username"
ip link set dev "$1" up
fi
}
## Delete TAP interface
# $1: name of the interface to delete
function del_tap()
{
say "Deleting TAP interface '$1'"
ip link set dev "$1" down
ip tuntap del "$1" mode tap
}
## Check if the bridge has any interface
# $1: bridge interface name
function bridge_is_empty()
{
[[ $(ls "/sys/class/net/$1/brif" | wc -w) == "0" ]]
}
## Create bridge interface if it does not exist
# $1: bridge interface name
function create_br()
{
if is_interface "$1"; then
if [[ ! -d "/sys/class/net/$1/brif" ]]; then
error "Interface '$1' already exists and is not a bridge"
exit 1
fi
else
say "Creating bridge interface '$1'"
brctl addbr "$1"
#ip link add name "$1" type bridge
ip link set dev "$1" up
# Xyne's excellent script to launch NAT
say "Starting NAT"
kerndev-nat-launch.sh "$wan_nic" "$1" up
fi
}
## Delete bridge interface if it exists and has no interface
# $1: bridge interface name
function del_br()
{
if bridge_is_empty "$1"; then
# Xyne's excellent script to kill NAT
say "Stopping NAT"
kerndev-nat-launch.sh "$wan_nic" "$1" down
say "Deleting bridge interface '$1'"
ip link set dev "$1" down
ip link delete "$1" type bridge
fi
}
## Add interface to the bridge
# $1: bridge interface name
# $2: name of the interface to add
function br_add_iface()
{
say "Adding interface '$2' to bridge '$1'"
ip link set dev "$2" promisc on up
ip addr flush dev "$2" scope host #&>/dev/null
ip addr flush dev "$2" scope site #&>/dev/null
ip addr flush dev "$2" scope global #&>/dev/null
#brctl addif $1 $2
ip link set dev "$2" master "$1"
# skip forwarding delay
#bridge link set dev "$2" state 3
#brctl setfd "$2" 0
}
## Remove interface from the bridge
# $1: bridge interface name
# $2: name of the interface to remove
function br_rm_iface()
{
say "Removing interface '$2' from bridge '$1'"
ip link set "$2" promisc off down
ip link set dev "$2" nomaster
}
########## Main ###############
function print_qemu_tap_helper_usage()
{
error "usage: $0 <username> <TAP interface> <bridge interface> <WAN interface> <up|down>"
error " <TAP interface> and <bridge interface> will be created,"
error " NAT from <WAN interface> to <bridge interface> will be set up"
}
if [[ $EUID -ne 0 ]]; then
error "This script must be run as root."
exit 1
fi
if [[ -z $4 ]]; then
print_qemu_tap_helper_usage
exit 1
else
username="$1"
tap_nic="$2"
br_nic="$3"
wan_nic="$4"
action="$5"
fi
# exit on errors
set -e
case "$action" in
up)
create_br "$br_nic"
create_tap "$tap_nic"
br_add_iface "$br_nic" "$tap_nic"
;;
down)
br_rm_iface "$br_nic" "$tap_nic"
del_tap "$tap_nic"
del_br "$br_nic"
;;
*)
print_qemu_tap_helper_usage
exit 1
;;
esac