]>
Commit | Line | Data |
---|---|---|
d61a01d4 MT |
1 | #!/bin/bash |
2 | ############################################################################### | |
3 | # # | |
4 | # IPFire.org - A linux based firewall # | |
5 | # Copyright (C) 2010 Michael Tremer & Christian Schmidt # | |
6 | # # | |
7 | # This program is free software: you can redistribute it and/or modify # | |
8 | # it under the terms of the GNU General Public License as published by # | |
9 | # the Free Software Foundation, either version 3 of the License, or # | |
10 | # (at your option) any later version. # | |
11 | # # | |
12 | # This program is distributed in the hope that it will be useful, # | |
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # | |
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # | |
15 | # GNU General Public License for more details. # | |
16 | # # | |
17 | # You should have received a copy of the GNU General Public License # | |
18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. # | |
19 | # # | |
20 | ############################################################################### | |
21 | ||
d1e71061 MT |
22 | BONDING_ALLOWED_MODES="balance-rr active-backup balance-xor broadcast 802.3ad \ |
23 | balance-tlb balance-alb" | |
24 | BONDING_MASTERS="/sys/class/net/bonding_masters" | |
a6fcc369 | 25 | BONDING_PORT_PATTERN="bN" |
d1e71061 | 26 | |
1c6a4e30 | 27 | bonding_init() { |
e72eb5c8 | 28 | module_load "bonding" |
711ffac1 MT |
29 | } |
30 | ||
1c6a4e30 | 31 | bonding_create() { |
d61a01d4 | 32 | local device=${1} |
d1e71061 MT |
33 | assert isset device |
34 | shift | |
35 | ||
36 | local address | |
37 | local mode="balance-rr" | |
38 | ||
39 | while [ $# -gt 0 ]; do | |
40 | case "${1}" in | |
41 | --address=*) | |
42 | address=$(cli_get_val ${1}) | |
43 | ;; | |
44 | --mode=*) | |
45 | mode=$(cli_get_val ${1}) | |
46 | ;; | |
47 | *) | |
48 | error "Unrecognized argument: ${1}" | |
49 | return ${EXIT_ERROR} | |
50 | ;; | |
51 | esac | |
52 | shift | |
53 | done | |
d61a01d4 | 54 | |
d1e71061 MT |
55 | if isset address; then |
56 | if ! ismac address; then | |
57 | log ERROR "Invalid mac address: ${address}" | |
58 | return ${EXIT_ERROR} | |
59 | fi | |
60 | fi | |
61 | ||
62 | if ! list_match "${mode}" ${BONDING_ALLOWED_MODES}; then | |
63 | log ERROR "Bonding mode is not supported: ${mode}" | |
64 | log ERROR "Valid modes are: ${BONDING_ALLOWED_MODES}" | |
65 | return ${EXIT_ERROR} | |
66 | fi | |
d61a01d4 | 67 | |
065a1bd1 MT |
68 | # Initialize the bonding driver just |
69 | # when we need it. | |
70 | bonding_init | |
71 | ||
a6fcc369 MT |
72 | # Create the bonding device |
73 | if cmd ip link add "${device}" address "${address}" \ | |
74 | type bond mode "${mode}"; then | |
d1e71061 MT |
75 | log DEBUG "Successfully created bonding device '${device}'" |
76 | else | |
77 | log ERROR "Could not create bonding device '${device}'" | |
78 | return ${EXIT_ERROR} | |
79 | fi | |
80 | ||
d1e71061 | 81 | return ${EXIT_OK} |
d61a01d4 MT |
82 | } |
83 | ||
1c6a4e30 | 84 | bonding_remove() { |
5bb2429a | 85 | local device=${1} |
711ffac1 MT |
86 | assert isset device |
87 | ||
d1e71061 | 88 | # Remove the device. |
a6fcc369 | 89 | if device_delete "${device}"; then |
d1e71061 MT |
90 | log DEBUG "Successfully removed bonding device '${device}'" |
91 | else | |
92 | log ERROR "Could not remove bonding device '${device}'" | |
93 | return ${EXIT_ERROR} | |
94 | fi | |
d61a01d4 | 95 | |
d1e71061 | 96 | return ${EXIT_OK} |
d61a01d4 MT |
97 | } |
98 | ||
1c6a4e30 | 99 | bonding_get_mode() { |
711ffac1 | 100 | local device=${1} |
d1e71061 | 101 | assert isset device |
711ffac1 MT |
102 | |
103 | local mode mode_num | |
104 | read mode mode_num < ${SYS_CLASS_NET}/${device}/bonding/mode | |
d1e71061 | 105 | print "${mode}" |
711ffac1 MT |
106 | } |
107 | ||
1c6a4e30 | 108 | bonding_set_mode() { |
e72eb5c8 MT |
109 | assert [ $# -eq 2 ] |
110 | ||
111 | local device="${1}" | |
112 | local mode="${2}" | |
113 | ||
644d3bb8 | 114 | if fappend "${SYS_CLASS_NET}/${device}/bonding/mode" "${mode}"; then |
e72eb5c8 MT |
115 | log DEBUG "Set mode of bond '${device}' to '${mode}'" |
116 | else | |
117 | log ERROR "Could not set mode of bond '${device}' to '${mode}'" | |
118 | return ${EXIT_ERROR} | |
119 | fi | |
120 | ||
121 | return ${EXIT_OK} | |
122 | } | |
123 | ||
1c6a4e30 | 124 | bonding_enslave_device() { |
5bb2429a | 125 | local device=${1} |
d1e71061 MT |
126 | assert isset device |
127 | ||
5bb2429a | 128 | local slave=${2} |
d1e71061 MT |
129 | assert isset slave |
130 | ||
d61a01d4 MT |
131 | shift 2 |
132 | ||
a6fcc369 MT |
133 | local slaves="$(bonding_get_slaves "${device}")" |
134 | if list_match "${slave}" ${slaves}; then | |
135 | log DEBUG "${slave} is already enslaved in ${device}" | |
136 | return ${EXIT_OK} | |
137 | fi | |
d1e71061 | 138 | |
a6fcc369 MT |
139 | # Slave must be down to be enslaved. |
140 | if ! device_set_down "${slave}"; then | |
d1e71061 MT |
141 | log ERROR "Cannot enslave '${slave}' because it cannot be set down." |
142 | return ${EXIT_ERROR} | |
143 | fi | |
711ffac1 | 144 | |
a6fcc369 MT |
145 | # Add it |
146 | cmd ip link set "${slave}" master "${device}" | |
d1e71061 | 147 | local ret=$? |
d61a01d4 | 148 | |
d1e71061 | 149 | if [ ${ret} -eq ${EXIT_OK} ]; then |
e72eb5c8 | 150 | log DEBUG "Successfully enslaved '${slave}' to '${device}'" |
d1e71061 | 151 | else |
e72eb5c8 | 152 | log ERROR "Could not enslave '${slave}' to '${device}'" |
d1e71061 MT |
153 | return ${EXIT_ERROR} |
154 | fi | |
155 | ||
156 | return ${EXIT_OK} | |
d61a01d4 | 157 | } |
711ffac1 | 158 | |
1c6a4e30 | 159 | bonding_get_slaves() { |
711ffac1 | 160 | local device=${1} |
d1e71061 MT |
161 | assert isset device |
162 | shift | |
163 | ||
164 | local file="slaves" | |
165 | while [ $# -gt 0 ]; do | |
166 | case "${1}" in | |
167 | --active) | |
168 | file="active_slave" | |
169 | ;; | |
170 | *) | |
171 | error "Unrecognized argument: ${1}" | |
172 | return ${EXIT_ERROR} | |
173 | ;; | |
174 | esac | |
175 | shift | |
176 | done | |
711ffac1 | 177 | |
d1e71061 MT |
178 | fread ${SYS_CLASS_NET}/${device}/bonding/${file} |
179 | ||
180 | return ${EXIT_OK} | |
711ffac1 MT |
181 | } |
182 | ||
1c6a4e30 | 183 | bonding_get_lacp_rate() { |
711ffac1 | 184 | local device=${1} |
d1e71061 | 185 | assert isset device |
711ffac1 | 186 | |
d1e71061 MT |
187 | local rate rateno |
188 | read -r rate rateno \ | |
189 | < ${SYS_CLASS_NET}/${device}/bonding/lacp_rate | |
711ffac1 | 190 | |
d1e71061 MT |
191 | print "${rate}" |
192 | return ${EXIT_OK} | |
193 | } | |
711ffac1 | 194 | |
1c6a4e30 | 195 | bonding_get_miimon() { |
711ffac1 | 196 | local device=${1} |
d1e71061 | 197 | assert isset device |
711ffac1 | 198 | |
d1e71061 | 199 | fread ${SYS_CLASS_NET}/${device}/bonding/miimon |
711ffac1 MT |
200 | } |
201 | ||
1c6a4e30 | 202 | bonding_set_miimon() { |
711ffac1 | 203 | local device=${1} |
d1e71061 | 204 | assert isset device |
711ffac1 | 205 | |
d1e71061 MT |
206 | local miimon=${2} |
207 | assert isset miimon | |
711ffac1 | 208 | |
d1e71061 | 209 | print "${miimon}" > ${SYS_CLASS_NET}/${device}/bonding/miimon |
711ffac1 MT |
210 | } |
211 | ||
1c6a4e30 | 212 | bonding_slave_get_master() { |
711ffac1 | 213 | local slave=${1} |
711ffac1 | 214 | assert isset slave |
711ffac1 | 215 | |
d1e71061 MT |
216 | device_is_bonded ${slave} || return ${EXIT_ERROR} |
217 | ||
218 | local master=$(fread ${SYS_CLASS_NET}/${slave}/master/ifindex) | |
219 | if isset master; then | |
220 | device_ifindex_to_name ${master} | |
221 | return ${EXIT_OK} | |
222 | fi | |
711ffac1 MT |
223 | |
224 | return ${EXIT_ERROR} | |
225 | } |