Author Topic: [HOWTO] interface bonding using bond0 (also connected to bridge br0)  (Read 8480 times)

markus.neubauer

  • Zen Monk
  • **
  • Posts: 59
  • Karma: +8/-0
    • View Profile
In the 3.2 core it's easy to use bonding with the network.preservice, if you also need a bridge (example for kvm-qemu machines, connected to the outer world)

Prerequisites:
- Your interfaces support bonding (use ethtool to check)
- Configure the first bridge (br?) in zentyal network module and use the fixed address you need.
If you have modified the DFT variables, out of the box the code is desinged to work like ...

    [lan or wan]
         /  \
  [eth0]   [eth1]
       \      /
      [bond0]
          |
       [br?]

Warning: Dont use the following script without modification if you have more than one interface configured or virtual cards on your bridge in zentyal.

In the case you're still here, continue with ...
Code: [Select]
sudo apt-get install ifenslave
sudo modprobe bonding
sudo grep -q bonding /etc/modules || echo bonding >>/etc/modules

Then put a hook in /etc/zentyal/hooks/network.preservice with the following ...
Code: [Select]
#!/bin/bash

# Revision:        0.57
# Date:            2013-09-27
# Author:          Markus Neubauer
# License:         GPLv2
# Zentyal Version: 3.2
# Description:     Add bonding with bond0 using eth0/1 connected to a bridge on br?
#                      Use it as /etc/zentyal/hooks/network.preservice and make
#                      it executable
# Remarks:         Placed in public for the zentyal community at:
#                  http://forum.zentyal.org/index.php/topic,17839.html
# This script can safely be removed when zentyal has official support for bonded interfaces
# Prerequisites:   
# sudo apt-get install ifenslave
# comment next line out, if done so already in /etc/modules...
lsmod | grep -q "^bonding" || modprobe bonding
# uncomment next line to stop samba from searching an ip for bond0
# sed -i "s#ifaces_to_ignore = sit,tun#ifaces_to_ignore = bond,sit,tun#" /etc/zentyal/network.conf

# trunk interfaces
RAW_IF1="eth0" # modify this if using the new naming
RAW_IF2="eth1" # modify this if using the new naming
# ... extend to your needs and modify bond0 block if extended
# change "balance-alb" to your bonding mode if required

# Declare your own fallback variables, just in case something goes wrong
# adapt to your needs and put some meaningful values here
# you may safely want to delete the default definition for HWaddr, but set up your values for the rest
declare -r DFT_IF='0 inet static'       # THIS IS br0, oimitting the "br"
declare -r DFT_IPAddress='192.168.X.X'
declare -r DFT_NetMask='255.255.255.X'
declare -r DFT_BroadCast='192.168.X.255'
declare -r DFT_GateWay='192.168.X.X'
declare -r DFT_HWaddr='XX:XX:XX:XX:XX:XX' # you may want to try http://www.miniwebtool.com/mac-address-generator/
if [ 'XX:XX:XX:XX:XX:XX' = "${DFT_HWaddr}" ]; then
    echo "DOING NOTHING IN HOOK ${0} - NOT CONFIGURED on `date`" >>/etc/network/interfaces
    exit 1
fi

# backup zentyal config (debugging)
# makes you find a /etc/network/.interfaces.zentyal-hook.*.last
# which is the zentyal's fromer config
TMP_FILE="/etc/network/.interfaces.zentyal-hook.${0##*/}.last"
SAVE_FILE="${TMP_FILE}-`date`"
cp /etc/network/interfaces "${SAVE_FILE}"
[ -L "${TMP_FILE}" ] && rm "${TMP_FILE}"
ln -s "${SAVE_FILE}" "${TMP_FILE}"

TMP_FILE=`tempfile`

# save zentyal network module config variables
grep -m1 -A5 "iface br" /etc/network/interfaces  >${TMP_FILE}

TEMP_VAR=`grep -m1 'iface br' ${TMP_FILE}`
TEMP_VAR=${TEMP_VAR##*iface br}
IF=${TEMP_VAR:-${DFT_IF}}

TEMP_VAR=`grep -m1 address ${TMP_FILE}`
TEMP_VAR=${TEMP_VAR##*address }
IPAddress=${TEMP_VAR:-${DFT_IPAddress}}

TEMP_VAR=`grep -m1 netmask ${TMP_FILE}`
TEMP_VAR=${TEMP_VAR##*netmask }
NetMask=${TEMP_VAR:-${DFT_NetMask}}

TEMP_VAR=`grep -m1 broadcast ${TMP_FILE}`
TEMP_VAR=${TEMP_VAR##*broadcast }
BroadCast=${TEMP_VAR:-${DFT_BroadCast}}

TEMP_VAR=`grep -m1 gateway ${TMP_FILE}`
TEMP_VAR=${TEMP_VAR##*gateway }
GateWay=${TEMP_VAR:-${DFT_GateWay}}

TEMP_VAR=`grep -m1 'hwaddress ether' ${TMP_FILE}`
if [ -n "${DFT_HWaddr}" ]; then
        HWaddr=${DFT_HWaddr}
elif [ -f /sys/class/net/br${IF:0:1}/address ]; then
        HWaddr=`cat /sys/class/net/br${IF:0:1}/address`
elif [ -n "${TEMP_VAR}" ]; then
        HWaddr=${TEMP_VAR##*hwaddress ether }
fi

rm ${TMP_FILE}

# start a new config file with overwritting the previous one
echo "# replaced by zentyal hook ${0}
# on $(date)

auto lo
iface lo inet loopback

auto ${RAW_IF1}
iface ${RAW_IF1} inet manual
        bond-master bond0

auto ${RAW_IF2}
iface ${RAW_IF2} inet manual
        bond-master bond0

# add more raw interface blocks if needed (and extend the following bond)

# leave the bonded device entries above the bond entry
# to avoid race conditions in certain environments
auto bond0
iface bond0 inet manual
        bond-mode balance-alb        # should be selectable in GUI
        bond-miimon 100
        bond-lcap-rate 1
        bond-slaves ${RAW_IF1} ${RAW_IF2}
        up /sbin/ifconfig ${RAW_IF1} up || /bin/true
        up /sbin/ifconfig ${RAW_IF2} up || /bin/true
        up /sbin/ifenslave bond0 ${RAW_IF1} ${RAW_IF2} || /bin/true
        down /sbin/ifenslave -d bond0 ${RAW_IF1} ${RAW_IF2} || /bin/true
        post-down /sbin/ifconfig ${RAW_IF2} down || /bin/true
        post-down /sbin/ifconfig ${RAW_IF1} down || /bin/true

auto br${IF:0:1}
iface br${IF}" >/etc/network/interfaces

# restore zentyal network module config variables (append)
echo "        address ${IPAddress}" >>/etc/network/interfaces             
echo "        netmask ${NetMask}" >>/etc/network/interfaces               
echo "        broadcast ${BroadCast}" >>/etc/network/interfaces               
echo "        gateway ${GateWay}" >>/etc/network/interfaces             
[ -n "${HWaddr}" ] && echo "        hwaddress ether ${HWaddr}" >>/etc/network/interfaces

# append the rest of your config
echo "        bridge_ports bond0
        bridge_fd 9
        bridge_hello 2
        bridge_maxage 12
        bridge_stp off
        pre-up ifup bond0
        up /sbin/ifconfig ${RAW_IF1} up || /bin/true
        up /sbin/ifconfig ${RAW_IF2} up || /bin/true
        down /sbin/ifconfig ${RAW_IF1} down || /bin/true
        down /sbin/ifconfig ${RAW_IF2} down || /bin/true
        post-down ifdown bond0
# in the case you are using virtual hosts,
# you'll have to add the defines here, too!
#auto br${IF:0:1}:yourvhost
#iface br${IF:0:1}:yourvhost inet static
#        address <your_other_ip>
#        netmask <your_mask>
#        broadcast <your_bcast>

## eof" >>/etc/network/interfaces

exit 0
Make the script executable and test it by calling it yourself, review result in /etc/network/interfaces. Even if not all defs are necessary, i've tried to make the code failsafe...
Reconfiguring the zentyal dhcp module might be needed and also check your gateway/routing in the GUI

I had some trouble to get the routing back stable and have added a second (fallback) script as /etc/zentyal/hooks/network.postservice for the default route ...
Code: [Select]
#!/bin/sh
# change <your_gateway> to a meaningful ip and uncomment next line
#route -n | grep -q "^0.0.0.0" || /sbin/route add default gw <your_gateway>
(make it executable and test)

You could try ifdown br0 and then ifup br0 to see wether things are working. Be near to the console (just in case) or have IPMI access and enjoy your bonded if's.

You may also want to edit /etc/zentyal/network.conf:
Find the line containing:
ifaces_to_ignore = sit,tun,tap,lo,...
and change it to:
ifaces_to_ignore = bond,sit,tun,tap,lo,...
to avoid sambas searching for an ip on the bond interface (see sambas log). The drawback is you wont have access to this interface in the firewall.

It's easy to adapt if you just need bonding but no bridge, do not make the change to /etc/zentyal/network.conf and move the address configuration part of br to the bond defs and then remove the rest br part from code, see the following example ...
Code: [Select]
#!/bin/bash

# Revision:        0.58
# Date:            2013-10-04
# Author:          Markus Neubauer
# License:         GPLv2
# Zentyal Version: 3.2
# Description:     Add bonding with bond0 using eth0/1
#                      Use it as /etc/zentyal/hooks/network.preservice and make
#                      it executable
# Remarks:         Placed in public for the zentyal community at:
#                  http://forum.zentyal.org/index.php/topic,17839.html
# This script can safely be removed when zentyal has official support for bonded interfaces
# Prerequisites:   
# sudo apt-get install ifenslave
# comment next line out, if done so already in /etc/modules...
lsmod | grep -q "^bonding" || modprobe bonding

# trunk interfaces
RAW_IF1="eth0" # modify this if using the new naming
RAW_IF2="eth1" # modify this if using the new naming
# ... extend to your needs and modify bond0 block if extended
# change "balance-alb" to your bonding mode if required

# Declare your own fallback variables, just in case something goes wrong
# adapt to your needs and put some meaningful values here
# you may safely want to delete the default definition for HWaddr, but set up your values for the rest
declare -r DFT_IF='0 inet static'       # THIS IS bond0, oimitting the "bond"
declare -r DFT_IPAddress='192.168.X.X'
declare -r DFT_NetMask='255.255.255.X'
declare -r DFT_BroadCast='192.168.X.255'
declare -r DFT_GateWay='192.168.X.X'

# backup zentyal config (debugging)
# makes you find a /etc/network/.interfaces.zentyal-hook.*.last
# which is the zentyal's fromer config
TMP_FILE="/etc/network/.interfaces.zentyal-hook.${0##*/}.last"
SAVE_FILE="${TMP_FILE}-`date`"
cp /etc/network/interfaces "${SAVE_FILE}"
[ -L "${TMP_FILE}" ] && rm "${TMP_FILE}"
ln -s "${SAVE_FILE}" "${TMP_FILE}"

TMP_FILE=`tempfile`

# save zentyal network module config variables
grep -m1 -A5 "iface bond" /etc/network/interfaces  >${TMP_FILE}

TEMP_VAR=`grep -m1 'iface bond' ${TMP_FILE}`
TEMP_VAR=${TEMP_VAR##*iface bond}
IF=${TEMP_VAR:-${DFT_IF}}

TEMP_VAR=`grep -m1 address ${TMP_FILE}`
TEMP_VAR=${TEMP_VAR##*address }
IPAddress=${TEMP_VAR:-${DFT_IPAddress}}

TEMP_VAR=`grep -m1 netmask ${TMP_FILE}`
TEMP_VAR=${TEMP_VAR##*netmask }
NetMask=${TEMP_VAR:-${DFT_NetMask}}

TEMP_VAR=`grep -m1 broadcast ${TMP_FILE}`
TEMP_VAR=${TEMP_VAR##*broadcast }
BroadCast=${TEMP_VAR:-${DFT_BroadCast}}

TEMP_VAR=`grep -m1 gateway ${TMP_FILE}`
TEMP_VAR=${TEMP_VAR##*gateway }
GateWay=${TEMP_VAR:-${DFT_GateWay}}

rm ${TMP_FILE}

# start a new config file with overwritting the previous one
echo "# replaced by zentyal hook ${0}
# on $(date)

auto lo
iface lo inet loopback

auto ${RAW_IF1}
iface ${RAW_IF1} inet manual
        bond-master bond0

auto ${RAW_IF2}
iface ${RAW_IF2} inet manual
        bond-master bond0

# add more raw interface blocks if needed (and extend the following bond)

# leave the bonded device entries above the bond entry
# to avoid race conditions in certain environments
auto bond${IF:0:1}
iface bond${IF}" >/etc/network/interfaces

# restore zentyal network module config variables (append)
echo "        address ${IPAddress}" >>/etc/network/interfaces             
echo "        netmask ${NetMask}" >>/etc/network/interfaces               
echo "        broadcast ${BroadCast}" >>/etc/network/interfaces               
echo "        gateway ${GateWay}" >>/etc/network/interfaces             

# append the rest of your config
echo "        bond-mode balance-alb        # should be selectable in GUI
        bond-miimon 100
        bond-lcap-rate 1
        bond-slaves ${RAW_IF1} ${RAW_IF2}
        up /sbin/ifconfig ${RAW_IF1} up || /bin/true
        up /sbin/ifconfig ${RAW_IF2} up || /bin/true
        up /sbin/ifenslave bond0 ${RAW_IF1} ${RAW_IF2} || /bin/true
        down /sbin/ifenslave -d bond0 ${RAW_IF1} ${RAW_IF2} || /bin/true
        post-down /sbin/ifconfig ${RAW_IF2} down || /bin/true
        post-down /sbin/ifconfig ${RAW_IF1} down || /bin/true

# in the case you are using virtual hosts,
# you'll have to add the defines here, too!
#auto bond${IF:0:1}:yourvhost
#iface bond${IF:0:1}:yourvhost inet static
#        address <your_other_ip>
#        netmask <your_mask>
#        broadcast <your_bcast>

## eof" >>/etc/network/interfaces

exit 0
In the case your are using DHCP you should remove the addressing part and dont save the former setup in tmp which will make the script very short ;)
In recent versions of Ubuntu the code is very straight, you simply copy the following script  to /etc/zentyal/hooks/network.preservice ...
Code: [Select]
#!/bin/bash

# Revision:        0.59
# Date:            2013-10-04
# Author:          Markus Neubauer
# License:         GPLv2
# Zentyal Version: 3.2
# Description:     Add bonding with bond0 using eth0/1 on DHCP
#                      Use it as /etc/zentyal/hooks/network.preservice and make
#                      it executable
# Remarks:         Placed in public for the zentyal community at:
#                  http://forum.zentyal.org/index.php/topic,17839.html
# This script can safely be removed when zentyal has official support for bonded interfaces
# Prerequisites:   
# sudo apt-get install ifenslave
# comment next line out, if done so already in /etc/modules...
lsmod | grep -q "^bonding" || modprobe bonding

# change "balance-alb" to your bonding mode if required

# start a new config file with overwritting the previous one
echo "# replaced by zentyal hook ${0}
# on $(date)

auto lo
iface lo inet loopback

# raw network interface 1
auto eth0
iface eth0 inet manual
        bond-master bond0

# raw network interface 2
auto eth1
iface eth1 inet manual
        bond-master bond0

auto bond0
iface bond0 inet dhcp
        bond-mode balance-alb
        bond-miimon 100
        bond-lcap-rate 1
        bond-slaves eth0 eth1
iface bond0 inet6 auto

# in the case you are using virtual hosts,
# you'll have to add the defines here, too!
#auto bond0:yourvhost
#iface bond0:yourvhost inet static
#        address <your_other_ip>
#        netmask <your_mask>
#        broadcast <your_bcast>

## eof" >/etc/network/interfaces

If you are using KVM/QEMU, for a powerful and fast way of bridging, and if you are using bonding without a (userspace) own bridge, you may want to look at macvtap device support for the kvm/qemu (modprobe vhost_net) which will give you a kernel bridge and full access from internet side if you use the virtio bridge mode. The xml part for qemu looks similar like ...
Code: [Select]
    <interface type='direct'>
      <mac address='<your mac address>'/>
      <source dev='bond0' mode='bridge'/>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
    </interface>
... which gives you the qemu parameter part -netdev tap,id=hostnet0,vhost=on -device virtio-net-pci,netdev=hostnet0,id=net0,mac=<your mac address>,bus=pci.0,addr=0x4
The drawback of this solution is, you wont ping your virtual host from bare metal host and may want to have a second (internal bridge) interface to access host from virtual host and vs. - or return to the first solution here. You then use the vhost-net to connect via a vnet interface on the bridge. You still can use a macvtap device, connected to the bond, to achive full speed on an other kvm machine. Some may think about "if I use Zentyal in a KVM and setup a second one in a KVM I can test changes before going to production mode"...

... adapt the settings for your interfaces as needed, suggestions are welcome.
Maybe someone could come along with a nice UI part for this purpose in the network module.

hth Markus

You may want to read https://www.kernel.org/doc/Documentation/networking/bonding.txt and
an example for a complex network config can be found here: https://www.stgraber.org/download/complex-interfaces
A mac-address generator for the bridge was found here http://www.miniwebtool.com/mac-address-generator/
« Last Edit: October 08, 2013, 06:58:44 pm by markus.neubauer »

gerald_FS

  • Guest
Re: [HOWTO] interface bonding using bond0 connected to bridge br0
« Reply #1 on: September 24, 2013, 07:25:00 pm »
Frage funktioniert der Ansatz auch noch bei der 3.2-Version?

Ich bekomme ihn nicht zum laufen, oder ich habe eine Zeile vergessen zu editieren...


Danke, ich finde den Ansatz total cool!

BrettonWoods

  • Guest
Re: [HOWTO] interface bonding using bond0 connected to bridge br0
« Reply #2 on: September 25, 2013, 12:28:22 am »
Top script Markus, used to do it by hand before.

I have often wondered why bonding for network throughput and redundancy isn't part of the defualt Zentyal offering.
Its a fairly simple method and a common requirement if you have more than a couple of users.

Is there any reason this isn't a Zentyal offering?

markus.neubauer

  • Zen Monk
  • **
  • Posts: 59
  • Karma: +8/-0
    • View Profile
Re: [HOWTO] interface bonding using bond0 connected to bridge br0
« Reply #3 on: September 27, 2013, 08:11:00 am »
Frage funktioniert der Ansatz auch noch bei der 3.2-Version?

Ich bekomme ihn nicht zum laufen, oder ich habe eine Zeile vergessen zu editieren...
The script is being used in 3.2 now, too.

Without further detail, it's hard to know, what goes wrong.
Can you execute the script by hand? See /etc/network/interfaces for results and post it here.

markus.neubauer

  • Zen Monk
  • **
  • Posts: 59
  • Karma: +8/-0
    • View Profile
Re: [HOWTO] interface bonding using bond0 connected to bridge br0
« Reply #4 on: September 27, 2013, 08:16:16 am »
Top script Markus, used to do it by hand before.
Thnx for the applaud ;)

I have often wondered why bonding for network throughput and redundancy isn't part of the defualt Zentyal offering.
Its a fairly simple method and a common requirement if you have more than a couple of users.

Is there any reason this isn't a Zentyal offering?
I guess - not enough questions for this solution. ;)
We use it because architects have big drawings stored in files wich are loaded from and saved on the server. If all people are working the systems response is better using both interfaces.

markus.neubauer

  • Zen Monk
  • **
  • Posts: 59
  • Karma: +8/-0
    • View Profile
Re: [HOWTO] interface bonding using bond0 connected to bridge br0
« Reply #5 on: September 27, 2013, 03:50:01 pm »
Ich bekomme ihn nicht zum laufen, oder ich habe eine Zeile vergessen zu editieren...

I've corrected a typo in the former script (online version), you should use the newer version above!
« Last Edit: October 05, 2013, 08:22:04 am by markus.neubauer »

gsoares

  • Zen Apprentice
  • *
  • Posts: 8
  • Karma: +0/-0
    • View Profile
Hi,

Anyone can you help me? Just the first interface is configured with bridge? I really lost access to this interface? I trying to do this without success, the interface appears, but just second interface reply my icmp, see:

ifconfig

bond0     Link encap:Ethernet  HWaddr 00:0c:29:4e:6f:b8 
          inet addr:172.16.71.1  Bcast:172.16.71.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MASTER MULTICAST  MTU:1500  Metric:1
          RX packets:19 errors:0 dropped:72 overruns:0 frame:0
          TX packets:270 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:1709 (1.7 KB)  TX bytes:16200 (16.2 KB)

eth0      Link encap:Ethernet  HWaddr 00:0c:29:4e:6f:b8 
          inet addr:10.10.20.64  Bcast:10.10.20.255  Mask:255.255.255.0
          UP BROADCAST RUNNING SLAVE MULTICAST  MTU:1500  Metric:1
          RX packets:19 errors:0 dropped:72 overruns:0 frame:0
          TX packets:270 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:1709 (1.7 KB)  TX bytes:16200 (16.2 KB)

eth1      Link encap:Ethernet  HWaddr 00:0c:29:4e:6f:c2 
          inet addr:10.10.10.25  Bcast:10.10.10.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8370 errors:0 dropped:33 overruns:0 frame:0
          TX packets:2342 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:839676 (839.6 KB)  TX bytes:853778 (853.7 KB)

lo        Link encap:Local Loopback 
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:1889 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1889 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:477296 (477.2 KB)  TX bytes:477296 (477.2 KB)


jbahillo

  • Zentyal Staff
  • Zen Hero
  • *****
  • Posts: 1444
  • Karma: +77/-2
    • View Profile
Very food tip.

BrettonWoods, bonding is included in 3.4