Creating a Bond Interface

From Mage
Jump to navigation Jump to search

A quick and dirty guide to bonding NICs with reliable device names.

Install packages

pacman -S ifenslave

package details - ifenslave



Find MAC address

Find the MAC address of the NICs you'd like to bond using ifconfig:

ifconfig -a

Example output is shown below. Make a note of the HWaddr of the interfaces you want to bond. We'll need these MAC addresses in the next step.

┌(foo@server)─(11:30 AM Tue Jun 25)─(~)
└> ifconfig -a

enp5s0    Link encap:Ethernet  HWaddr 00:1C:C0:AE:B5:E7
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0(0 MiB)  TX bytes:0 (0 MiB)

enp6s0    Link encap:Ethernet  HWaddr 00:1C:C0:AE:B5:E8
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0(0 MiB)  TX bytes:0 (0 MiB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:480 (480.0 b)  TX bytes:480 (480.0 b)

wan       Link encap:Ethernet  HWaddr 00:1C:C0:AE:B5:E6
          inet addr:192.168.1.1  Bcast:192.168.1.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:41620 errors:0 dropped:0 overruns:0 frame:0
          TX packets:40231 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:21601203 (20.6 MiB)  TX bytes:6145876 (5.8 MiB)


Set udev rules

We're going to set a udev rule that renames the interfaces upon boot and starts any services that may depend on them. The following rule will look for the MAC addresses we noted in the previous step (make sure the letters are in lowercase in this file). If found, it will rename the interfaces from the kernel generated ones to the names of our choosing. Here we're renaming enp*s0 to lan*. This will help give us reliable names to use when referring to the devices. Avoid using names the kernel may use by default such as eth0.

vi /etc/udev/rules.d/40-bond0.rules

SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="00:1c:c0:ae:b5:e7", NAME="lan0"
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="00:1c:c0:ae:b5:e8", NAME="lan1"
ENV{SYSTEMD_WANTS}="network@bond0.service"


Create systemd service

You may have noticed the reference to network@bond0.service in the previous step. This lets udev know to start a systemd service named network@bond0.service after the interfaces have been renamed to lan0 and lan1. Systemd can be a true pain in the butt when trying to set services to only come online after a network interface is up, so let's create a framework where services can be specified in the interface's startup service. We can do this using an old school init.d style script. Because this is launched via udev, we don't need to bother with systemd's [Install] section or actually enabling this service.


vi /etc/systemd/system/network\@bond0.service

[Unit]
Description=Network Connectivity (bond0)

[Service]
Type=oneshot
RemainAfterExit=yes

ExecStart=/etc/network/bond0.sh start

ExecStop=/etc/network/bond0.sh stop


Create the network init script

Remember to set the script to executable only by root after it's creation by issuing:

touch /etc/network/bond0.sh
chown root:root /etc/network/bond0.sh
chmod 700 /etc/network/bond0.sh


vi /etc/network/bond0.sh

#!/bin/bash
#
# Wait for lan port renames and bring the bond interface up.

start() {
   if [ -n "`ip link | grep bond0`" ]; then
      echo -n "Attempting to bring up bond0 : Interface bond0 is already up!"
      return
   else
      while [ -z "`ip link | grep bond0`" ]
      do
         echo -n "Attempting to bring up bond0 : "

         # Test to see if the LAN ports have been assigned yet.
         lan_status=`ip link`
         lan_up=`echo $lan_status | grep lan0 | grep lan1`

         if [ "$lan_up" ]; then
            ip link add name bond0 type bond
            # Add a separate subnet for the device to route on.
            ip addr add dev bond0 192.168.5.1/24 broadcast 192.168.5.255
            ip link set dev lan0 up
            ip link set dev lan1 up
            ip link set dev bond0 up
            ifenslave bond0 lan0
            ifenslave bond0 lan1
            # Enhance the send/receive windows on this route
            ip route change 192.168.5.0/24 dev bond0 proto kernel scope link src 192.168.5.1 initcwnd 65 initrwnd 65

            # Start any services that depend on this NIC HERE
            #mount -t cifs //SERVER/sharename /var/cache/pacman/pkg -o username=username,password=password,uid=username,gid=group,iocharset=utf8
         else
            echo "LAN ports unavailable, waiting 0.1s."
            sleep 0.1
         fi
      done
   fi

   echo -n "Done."
   return
}

stop() {
   echo -n "Bringing down interface bond0 : "

   # Stop any services that depend on this NIC HERE
   #umount /var/cache/pacman/pkg

   ip link set lan1 nomaster
   ip link set lan0 nomaster
   ip link set dev lan1 down
   ip link set dev lan0 down
   ip link set dev bond0 down
   ip link delete bond0 type bond >/dev/null 2>&1

   echo -n "Done."
   return
}

status() {
   if [ "`which ifconfig`" ]; then
      ifconfig bond0
      echo
   fi

   ip link show bond0
}

restart() {
   stop
   echo ""
   start
}

case "$1" in
   start)
      start
      ;;
   stop)
      stop
      ;;
   status)
      status
      ;;
   restart)
      restart
      ;;
   reload)
      restart
      ;;
   *)
      echo -n "   Usage: ./bond0.sh (start | stop | status | restart | reload)"
      ;;
esac


Reboot

Reboot your machine to verify the changes have been applied correctly. Make sure the NICs have been renamed and that they have been assigned to the bond. Verify that any services that depend on the bond interface have started correctly.