diff --git a/net/bonding/Makefile b/net/bonding/Makefile new file mode 100644 index 000000000..c808666b3 --- /dev/null +++ b/net/bonding/Makefile @@ -0,0 +1,41 @@ +# +# Copyright (C) 2018 TDT AG +# +# This is free software, licensed under the GNU General Public License v2. +# See https://www.gnu.org/licenses/gpl-2.0.txt for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=proto-bonding +PKG_VERSION:=2018-06-11 +PKG_RELEASE:=1 + +PKG_LICENSE:=GPL-2.0 +PKG_LICENSE_FILES:= + +PKG_MAINTAINER:=Helge Mader + +include $(INCLUDE_DIR)/package.mk + +define Package/proto-bonding + SECTION:=net + CATEGORY:=Network + TITLE:=Link Aggregation (Channel Bonding) proto handler + DEPENDS:=+kmod-bonding +endef + +define Package/proto-bonding/description + This package contains the channel bonding proto handler for netifd +endef + +define Build/Compile +endef + +define Package/proto-bonding/install + $(INSTALL_DIR) $(1)/lib/netifd/proto/ + $(INSTALL_BIN) ./files/lib/netifd/proto/bonding.sh \ + $(1)/lib/netifd/proto/ +endef + +$(eval $(call BuildPackage,proto-bonding)) diff --git a/net/bonding/files/lib/netifd/proto/bonding.sh b/net/bonding/files/lib/netifd/proto/bonding.sh new file mode 100755 index 000000000..b624738fe --- /dev/null +++ b/net/bonding/files/lib/netifd/proto/bonding.sh @@ -0,0 +1,211 @@ +#!/bin/sh +# +# Copyright (C) 2018 TDT AG +# +# This is free software, licensed under the GNU General Public License v2. +# See https://www.gnu.org/licenses/gpl-2.0.txt for more information. +# + +. /lib/functions.sh +. ../netifd-proto.sh + +init_proto "$@" + +INCLUDE_ONLY=1 + +BONDING_MASTERS="/sys/class/net/bonding_masters" + +set_driver_values() { + local varname + + for varname in "$@"; do + local value + json_get_var value "$varname" + + [ -n "$value" ] && echo "$value" > /sys/class/net/"$link"/bonding/"$varname" + done +} + +proto_bonding_init_config() { + no_device=1 + available=1 + + proto_config_add_string "ifname" + + proto_config_add_string "ipaddr" + proto_config_add_string "netmask" + + proto_config_add_string "bonding_policy" + proto_config_add_string "link_monitoring" + proto_config_add_string "slaves" + proto_config_add_string "all_slaves_active" + + proto_config_add_string "min_links" + proto_config_add_string "ad_actor_sys_prio" + proto_config_add_string "ad_actor_system" + proto_config_add_string "ad_select" + proto_config_add_string "lacp_rate" + proto_config_add_string "packets_per_slave" + proto_config_add_string "xmit_hash_policy" + proto_config_add_string "primary" + proto_config_add_string "primary_reselect" + proto_config_add_string "lp_interval" + proto_config_add_string "tlb_dynamic_lb" + proto_config_add_string "resend_igmp" + proto_config_add_string "fail_over_mac" + proto_config_add_string "num_grat_arp__num_unsol_na" + + proto_config_add_string "arp_interval" + proto_config_add_string "arp_ip_target" + proto_config_add_string "arp_all_targets" + proto_config_add_string "arp_validate" + + proto_config_add_string "miimon" + proto_config_add_string "downdelay" + proto_config_add_string "updelay" + proto_config_add_string "use_carrier" +} + +proto_bonding_setup() { + local cfg="$1" + local link="bonding-$cfg" + + # Check for loaded kernel bonding driver (/sys/class/net/bonding_masters exists) + [ -f "$BONDING_MASTERS" ] || { + echo "$cfg" "setup: bonding_masters does not exist in sysfs (kernel module not loaded?)" + proto_notify_error "$cfg" "setup: bonding_masters does not exist in sysfs (kernel module not loaded?)" + proto_block_restart "$cfg" + return + } + + # Add bonding interface to system + echo "+$link" > "$BONDING_MASTERS" + + # Set bonding policy (with corresponding parameters) + local bonding_policy + json_get_vars bonding_policy + + case "$bonding_policy" in + + 802.3ad) + echo "$bonding_policy" > /sys/class/net/"$link"/bonding/mode + set_driver_values min_links ad_actor_sys_prio ad_actor_system ad_select lacp_rate + ;; + + balance-rr) + echo "$bonding_policy" > /sys/class/net/"$link"/bonding/mode + set_driver_values packets_per_slave xmit_hash_policy + ;; + + balance-tlb) + echo "$bonding_policy" > /sys/class/net/"$link"/bonding/mode + set_driver_values primary primary_reselect lp_interval tlb_dynamic_lb resend_igmp xmit_hash_policy + ;; + + balance-alb) + echo "$bonding_policy" > /sys/class/net/"$link"/bonding/mode + set_driver_values primary primary_reselect lp_interval tlb_dynamic_lb resend_igmp xmit_hash_policy + ;; + + active-backup) + echo "$bonding_policy" > /sys/class/net/"$link"/bonding/mode + set_driver_values primary primary_reselect fail_over_mac num_grat_arp__num_unsol_na xmit_hash_policy + ;; + esac + + # Set link monitoring (with corresponding parameters) + local link_monitoring + json_get_vars link_monitoring + + case "$link_monitoring" in + + arp) + local arp_interval arp_ip_target arp_all_targets arp_validate + json_get_vars arp_interval arp_ip_target arp_all_targets arp_validate + + [ -n "$arp_interval" -a "$arp_interval" != 0 ] && echo "$arp_interval" > /sys/class/net/"$link"/bonding/arp_interval + + IFS=' ' + for target in $arp_ip_target; do + echo "+$target" > /sys/class/net/"$link"/bonding/arp_ip_target + done + + [ -n "$arp_all_targets" ] && echo "$arp_all_targets" > /sys/class/net/"$link"/bonding/arp_all_targets + [ -n "$arp_validate" ] && echo "$arp_validate" > /sys/class/net/"$link"/bonding/arp_validate + ;; + + mii) + local miimon downdelay updelay use_carrier + json_get_vars miimon downdelay updelay use_carrier + + [ -n "$miimon" -a "$miimon" != 0 ] && echo "$miimon" > /sys/class/net/"$link"/bonding/miimon + [ -n "$downdelay" ] && echo "$downdelay" > /sys/class/net/"$link"/bonding/downdelay + [ -n "$updelay" ] && echo "$updelay" > /sys/class/net/"$link"/bonding/updelay + [ -n "$use_carrier" ] && echo "$use_carrier" > /sys/class/net/"$link"/bonding/use_carrier + ;; + esac + + # Add slaves to bonding interface + local slaves + json_get_vars slaves + + for slave in $slaves; do + + if [ "$(cat /proc/net/dev |grep "$slave")" == "" ]; then + echo "$cfg" "ERROR IN CONFIGURATION - $slave: No such device" + proto_notify_error "$cfg" "ERROR IN CONFIGURATION - $slave: No such device" + proto_block_restart "$cfg" + return + fi + + ifconfig "$slave" down + + sleep 1 + + echo "+$slave" > /sys/class/net/"$link"/bonding/slaves + + ifconfig "$slave" up + done + + [ -n "$all_slaves_active" ] && echo "$all_slaves_active" > /sys/class/net/"$link"/bonding/all_slaves_active + + local ipaddr netmask + json_get_vars ipaddr netmask + + # ATTENTION + #All json vars have to be read before the line below, as the + # json object will be overwritten by proto_init_update + # ATTENTION + + proto_init_update "$link" 1 + + # For static configuration we _MUST_ have an IP address + [ -z "$ipaddr" ] && { + echo "$cfg" "INVALID LOCAL ADDRESS" + proto_notify_error "$cfg" "INVALID_LOCAL_ADDRESS" + proto_block_restart "$cfg" + return + } + + proto_add_ipv4_address "$ipaddr" "$netmask" + + proto_send_update "$cfg" +} + +proto_bonding_teardown() { + local cfg="$1" + local link="bonding-$cfg" + + # Check for loaded kernel bonding driver (/sys/class/net/bonding_masters exists) + [ -f "$BONDING_MASTERS" ] || { + echo "$cfg" "teardown: bonding_masters does not exist in sysfs (kernel module not loaded?)" + proto_notify_error "$cfg" "teardown: bonding_masters does not exist in sysfs (kernel module not loaded?)" + proto_block_restart "$cfg" + return + } + + echo "-$link" > /sys/class/net/bonding_masters + logger "bonding_teardown($1): $2" +} + +add_protocol bonding