1#
2# Copyright (c) 2005 XenSource Ltd.
3#
4# This library is free software; you can redistribute it and/or
5# modify it under the terms of version 2.1 of the GNU Lesser General Public
6# License as published by the Free Software Foundation.
7#
8# This library is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11# Lesser General Public License for more details.
12#
13# You should have received a copy of the GNU Lesser General Public
14# License along with this library; If not, see <http://www.gnu.org/licenses/>.
15#
16
17
18# Gentoo doesn't have ifup/ifdown, so we define appropriate alternatives.
19
20# Other platforms just use ifup / ifdown directly.
21
22##
23# preiftransfer
24#
25# @param $1 The current name for the physical device, which is also the name
26#           that the virtual device will take once the physical device has
27#           been renamed.
28
29if ! which ifup >/dev/null 2>/dev/null
30then
31  preiftransfer()
32  {
33    true
34  }
35  ifup()
36  {
37    false
38  }
39  ifdown()
40  {
41    false
42  }
43else
44  preiftransfer()
45  {
46    true
47  }
48fi
49
50
51first_file()
52{
53  t="$1"
54  shift
55  for file in $@
56  do
57    if [ "$t" "$file" ]
58    then
59      echo "$file"
60      return
61    fi
62  done
63}
64
65find_dhcpd_conf_file()
66{
67  first_file -f /etc/dhcp/dhcpd.conf /etc/dhcp3/dhcpd.conf /etc/dhcpd.conf
68}
69
70
71find_dhcpd_init_file()
72{
73  first_file -x /etc/init.d/{isc-dhcp-server,dhcp-server,dhcp3-server,dhcp,dhcpd}
74}
75
76find_dhcpd_arg_file()
77{
78  first_file -f /etc/sysconfig/dhcpd /etc/defaults/dhcp /etc/default/dhcp-server /etc/default/dhcp3-server
79}
80
81# configure interfaces which act as pure bridge ports:
82_setup_bridge_port() {
83    local dev="$1"
84    local virtual="$2"
85
86    # take interface down ...
87    ip link set dev ${dev} down
88
89    if [ $virtual -ne 0 ] ; then
90        # Initialise a dummy MAC address. We choose the numerically
91        # largest non-broadcast address to prevent the address getting
92        # stolen by an Ethernet bridge for STP purposes.
93        # (FE:FF:FF:FF:FF:FF)
94        ip link set dev ${dev} address fe:ff:ff:ff:ff:ff || true
95    fi
96
97    # ... and configure it
98    ip address flush dev ${dev}
99}
100
101setup_physical_bridge_port() {
102    _setup_bridge_port $1 0
103}
104setup_virtual_bridge_port() {
105    _setup_bridge_port $1 1
106}
107
108# Usage: create_bridge bridge
109create_bridge () {
110    local bridge=$1
111
112    # Don't create the bridge if it already exists.
113    if [ ! -e "/sys/class/net/${bridge}/bridge" ]; then
114        if which brctl >&/dev/null; then
115            brctl addbr ${bridge}
116            brctl stp ${bridge} off
117            brctl setfd ${bridge} 0
118        else
119            ip link add name ${bridge} type bridge stp_state 0 forward_delay 0
120        fi
121    fi
122}
123
124# Usage: add_to_bridge bridge dev
125add_to_bridge () {
126    local bridge=$1
127    local dev=$2
128
129    # Don't add $dev to $bridge if it's already on the bridge.
130    if [ ! -e "/sys/class/net/${bridge}/brif/${dev}" ]; then
131        log debug "adding $dev to bridge $bridge"
132        if which brctl >&/dev/null; then
133            brctl addif ${bridge} ${dev}
134        else
135            ip link set ${dev} master ${bridge}
136        fi
137    else
138        log debug "$dev already on bridge $bridge"
139    fi
140
141    ip link set dev ${dev} up
142}
143
144remove_from_bridge () {
145    local bridge=$1
146    local dev=$2
147
148    do_without_error ip link set dev ${dev} down
149
150    # Don't remove $dev from $bridge if it's not on the bridge.
151    if [ -e "/sys/class/net/${bridge}/brif/${dev}" ]; then
152        log debug "removing $dev from bridge $bridge"
153        if which brctl >&/dev/null; then
154            do_without_error brctl delif ${bridge} ${dev}
155        else
156            do_without_error ip link set ${dev} nomaster
157        fi
158    else
159        log debug "$dev not on bridge $bridge"
160    fi
161}
162
163# Usage: set_mtu bridge dev
164set_mtu () {
165    local bridge=$1
166    local dev=$2
167    local type_if=$3
168
169    XENBUS_PATH="${XENBUS_PATH:?}"
170
171    local mtu=$(xenstore_read_default "$XENBUS_PATH/mtu" "")
172    if [ -z "$mtu" ]
173    then
174        mtu="`ip link show dev ${bridge}| awk '/mtu/ { print $5 }'`"
175        if [ -n "$mtu" ]
176        then
177            log debug "$bridge MTU is $mtu"
178        fi
179    fi
180    if [ -n "$mtu" ] && [ "$mtu" -gt 0 ]
181    then
182        log debug "setting $dev MTU to $mtu"
183        ip link set dev ${dev} mtu ${mtu} || :
184
185        if [ ${type_if} = vif ]
186        then
187            local dev_=${dev#vif}
188            local domid=${dev_%.*}
189            local devid=${dev_#*.}
190
191            local FRONTEND_PATH="/local/domain/$domid/device/vif/$devid"
192
193            xenstore_write "$FRONTEND_PATH/mtu" ${mtu}
194        fi
195    fi
196}
197