summaryrefslogtreecommitdiffstats
path: root/main/bonding/bonding.pre-up
blob: 69f6fbe261aaffc26b286040ea916df7ceabf539 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#!/bin/sh

[ "$VERBOSITY" = 1 ] && set -x

IFSTATE=/var/run/ifstate

add_master()
{
	# Return if $BOND_MASTER is already a bonding interface.
	[ -f "/sys/class/net/$BOND_MASTER/bonding/slaves" ] && return

	# If the bonding module is not yet loaded, load it.
	if [ ! -r /sys/class/net/bonding_masters ]; then
		modprobe -q bonding
	fi

	# Create the master interface.
	if ! grep -sq "\\<$BOND_MASTER\\>" /sys/class/net/bonding_masters; then
		echo "+$BOND_MASTER" > /sys/class/net/bonding_masters
	fi
}

sysfs()
{
	# Called with :
	# $1 = value to write. Won't write if $1 is empty.
	# $2 = basename of the file in bonding/ to write to.
	if [ "$1" ] ; then
		echo "$1" > "/sys/class/net/$BOND_MASTER/bonding/$2"
		return $?
	fi
	return 0
}

sysfs_add()
{
	# Called with :
	# $1 = values to write.
	# $2 = target filename.
	for value in $1; do
		# Do not add $1 to $2 if already present.
		if ! grep -sq "\\<$value\\>" /sys/class/net/$BOND_MASTER/bonding/$2
		then
		    sysfs "+$value" "$2"
		fi 
	done
}

ifup_slave()
{
	local v=
	[ "$VERBOSITY" = 1 ] && v=-v
	if [ "$1" != "$IFACE" ] && ! grep -q "^$1=" $IFSTATE && ifup -n "$1" >/dev/null 2>&1; then
		ifup $v $1
	fi
}

enslave_slaves()
{
	case "$BOND_SLAVES" in
		none)
			BOND_SLAVES=""
			;;
		all)
			BOND_SLAVES=`sed -ne 's/ *\(eth[^:]*\):.*/\1/p' /proc/net/dev`
			AUTOIF="yes"
			;;
	esac

	for slave in $BOND_SLAVES ; do
		if ( [ "$AUTOIF" ] && grep -q "^$slave=" $IFSTATE ) ; then
			echo "Not enslaving interface $slave since it is already configured"
		else
			# Ensure $slave is down.
			ip link set "$slave" down 2>/dev/null
			if ! sysfs_add "$slave" slaves 2>/dev/null ; then
				echo "Failed to enslave $slave to $BOND_MASTER. Is $BOND_MASTER ready and a bonding interface ?" >&2
			else
				# Bring up slave if it is defined in interfaces 
				# This is usefull to bring up slaves that need extra setup.
				ifup_slave $slave
			fi
		fi
	done
}

setup_master()
{
	sysfs "$IF_BOND_MODE" mode
	sysfs "$IF_BOND_MIIMON" miimon
	sysfs "$IF_BOND_USE_CARRIER" use_carrier
	sysfs "$IF_BOND_UPDELAY" updelay
	sysfs "$IF_BOND_DOWNDELAY" downdelay
	sysfs "$IF_BOND_ARP_INTERVAL" arp_interval
	sysfs "$IF_BOND_ARP_VALIDATE" arp_validate
	sysfs "$IF_BOND_FAIL_OVER_MAC" fail_over_mac
	sysfs "$IF_BOND_XMIT_HASH_POLICY" xmit_hash_policy
	sysfs "$IF_BOND_LACP_RATE" lacp_rate
	sysfs_add "$IF_BOND_ARP_IP_TARGET" arp_ip_target
}

setup_slaves()
{
	# The first slave in bond-primary found in current slaves becomes the primary.
	# If no slave in bond-primary is found, then primary does not change.
	for slave in $IF_BOND_PRIMARY ; do
		if grep -sq "\\<$slave\\>" "/sys/class/net/$BOND_MASTER/bonding/slaves" ; then
			sysfs "$slave" primary
			break
		fi
	done

	if [ "$IF_BOND_ACTIVE_SLAVE" ] ; then
		# Need to force interface up before. Bonding will refuse to activate a down interface.
		ip link set "$IF_BOND_ACTIVE_SLAVE" up
		sysfs "$IF_BOND_ACTIVE_SLAVE" active_slave
	fi
}

# Are there anything to do ?

# Option slaves deprecated, replaced by bond-slaves, but still supported for backward compatibility.
IF_BOND_SLAVES=${IF_BOND_SLAVES:-$IF_SLAVES}

if [ "$IF_BOND_MASTER" ] ; then
	BOND_MASTER="$IF_BOND_MASTER"
	BOND_SLAVES="$IFACE"
else
	if [ "$IF_BOND_SLAVES" ] ; then
		BOND_MASTER="$IFACE"
		BOND_SLAVES="$IF_BOND_SLAVES"
	fi
fi

# Exit if nothing to do...
[ -z "$BOND_MASTER$BOND_SLAVES" ] && exit

add_master
setup_master
enslave_slaves
setup_slaves