#!/bin/bash
# License: GPL 
# Author: Steven Shiau <steven _at_ clonezilla org>
# Description: Program to enable channel bonding.
# Ref:
# https://www.kernel.org/doc/Documentation/networking/bonding.txt
# https://backdrift.org/manage-linux-bonding-without-ifenslave-using-sysfs

# Load DRBL setting and functions
DRBL_SCRIPT_PATH="${DRBL_SCRIPT_PATH:-/usr/share/drbl}"

. $DRBL_SCRIPT_PATH/sbin/drbl-conf-functions
. /etc/drbl/drbl-ocs.conf
. $DRBL_SCRIPT_PATH/sbin/ocs-functions

# Load the config in ocs-live.conf. This is specially for Clonezilla live. It will overwrite some settings of /etc/drbl/drbl-ocs.conf, such as $DIA...
[ -e "/etc/ocs/ocs-live.conf" ] && . /etc/ocs/ocs-live.conf

# Settings
# default_link_det_timeout is loaded from drbl-ocs.conf
# Functions
USAGE() {
   echo "Usage: $0 [OPTION] NIC1 NIC2..."
   echo "OPTION"
   echo " -t, --timeout  NO  Assign the timeout NO in secs when detecting the linking status of a NIC. Default is $default_link_det_timeout secs."
   echo
   echo "Ex:"
   echo "To bond eth0 and eth1, run"
   echo "   $ocs eth0 eth1"
}

####################
### Main program ###
####################

ocs_file="$0"
ocs=`basename $ocs_file`
#
while [ $# -gt 0 ]; do
  case "$1" in
    -t|--timeout)
	shift
        if [ -z "$(echo $1 |grep ^-.)" ]; then
          # skip the -xx option, in case 
	  ocs_netlink_timeout="$1"
	  shift
        fi
	;;
    -*) echo "${0}: ${1}: invalid option" >&2
        USAGE >& 2
        exit 2 ;;
    *)  break ;;
  esac
done
# 
bond_nics="$*"

check_if_root

ask_and_load_lang_set $specified_lang

# check DIA
check_DIA_set_ESC $DIA

[ -z "$ocs_netlink_timeout" ] && ocs_netlink_timeout="$default_link_det_timeout"

if [ -z "$bond_nics" ]; then
  ask_nic_dev "$msg_select_nics_for_channel_bonding" checklist 2 # Obtain $chosen_nics
  bond_nics="$chosen_nics"
fi

nic_no="$(echo $bond_nics | wc -w)"
if [ "$nic_no" -lt 2 ]; then
   [ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE
   echo "For channel bonding, at least two NIC are required."
   echo "The selected device: $bond_nics"
   [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
   echo "$msg_program_stop!"
   my_ocs_exit 1
fi

# Disable the device first.
for id_s in $bond_nics; do
  ip link set $id_s down
  ip add flush $id_s
done
bnd_dev="$(cat /sys/class/net/bonding_masters 2>/dev/null)"
if [ -n "$bnd_dev" ]; then
  echo "-${bnd_dev}" > /sys/class/net/bonding_masters
fi

# Enable channel bonding
modprobe bonding
echo "+bond0" >  /sys/class/net/bonding_masters
echo 802.3ad > /sys/class/net/bond0/bonding/mode
echo 100 > /sys/class/net/bond0/bonding/miimon
ip link set bond0 up
for id_s in $bond_nics; do
  echo "+${id_s}" > /sys/class/net/bond0/bonding/slaves
done

# Show results
bnd_masters="$(cat /sys/class/net/bonding_masters 2>/dev/null)"
bnd_slaves="$(cat /sys/class/net/bond0/bonding/slaves 2>/dev/null)"
if [ -n "$bnd_masters" -a -n "$bnd_slaves" ]; then
  [ "$BOOTUP" = "color" ] && $SETCOLOR_SUCCESS
  echo "The channel bonding card was created successfully: $bnd_masters"
  [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
   ethtool bond0
   grep "^Slave Interface" /proc/net/bonding/bond0 
fi
