]>
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" | |
25 | ||
711ffac1 MT |
26 | function bonding_init() { |
27 | if ! grep -q "^bonding" /proc/modules; then | |
28 | modprobe bonding | |
29 | ||
30 | bonding_remove bond0 | |
31 | fi | |
32 | } | |
33 | ||
d61a01d4 MT |
34 | function bonding_create() { |
35 | local device=${1} | |
d1e71061 MT |
36 | assert isset device |
37 | shift | |
38 | ||
39 | local address | |
40 | local mode="balance-rr" | |
41 | ||
42 | while [ $# -gt 0 ]; do | |
43 | case "${1}" in | |
44 | --address=*) | |
45 | address=$(cli_get_val ${1}) | |
46 | ;; | |
47 | --mode=*) | |
48 | mode=$(cli_get_val ${1}) | |
49 | ;; | |
50 | *) | |
51 | error "Unrecognized argument: ${1}" | |
52 | return ${EXIT_ERROR} | |
53 | ;; | |
54 | esac | |
55 | shift | |
56 | done | |
d61a01d4 | 57 | |
d1e71061 MT |
58 | if isset address; then |
59 | if ! ismac address; then | |
60 | log ERROR "Invalid mac address: ${address}" | |
61 | return ${EXIT_ERROR} | |
62 | fi | |
63 | fi | |
64 | ||
65 | if ! list_match "${mode}" ${BONDING_ALLOWED_MODES}; then | |
66 | log ERROR "Bonding mode is not supported: ${mode}" | |
67 | log ERROR "Valid modes are: ${BONDING_ALLOWED_MODES}" | |
68 | return ${EXIT_ERROR} | |
69 | fi | |
d61a01d4 | 70 | |
065a1bd1 MT |
71 | # Initialize the bonding driver just |
72 | # when we need it. | |
73 | bonding_init | |
74 | ||
d1e71061 MT |
75 | # Create the bonding device. |
76 | print "+${device}" > ${BONDING_MASTERS} | |
77 | local ret=$? | |
d61a01d4 | 78 | |
d1e71061 MT |
79 | if [ ${ret} -eq ${EXIT_OK} ]; then |
80 | log DEBUG "Successfully created bonding device '${device}'" | |
81 | else | |
82 | log ERROR "Could not create bonding device '${device}'" | |
83 | return ${EXIT_ERROR} | |
84 | fi | |
85 | ||
86 | # Set the mode of the bonding device. | |
87 | print "${mode}" > ${SYS_CLASS_NET}/${device}/bonding/mode | |
88 | local ret=$? | |
89 | ||
90 | if [ ${ret} -ne ${EXIT_OK} ]; then | |
91 | log ERROR "Could not set mode of bonding device '${device}': ${Mmode}" | |
92 | return ${EXIT_ERROR} | |
93 | fi | |
94 | ||
95 | if isset address; then | |
96 | device_set_address ${device} ${address} | |
97 | fi | |
98 | ||
99 | return ${EXIT_OK} | |
d61a01d4 MT |
100 | } |
101 | ||
102 | function bonding_remove() { | |
5bb2429a | 103 | local device=${1} |
711ffac1 MT |
104 | assert isset device |
105 | ||
d1e71061 MT |
106 | if ! device_exists ${device}; then |
107 | return ${EXIT_ERROR} | |
108 | fi | |
d61a01d4 | 109 | |
d1e71061 | 110 | # Set device down if not already done. |
d61a01d4 | 111 | device_set_down ${device} |
d61a01d4 | 112 | |
d1e71061 MT |
113 | # Remove the device. |
114 | print "-${device}" > ${BONDING_MASTERS} | |
115 | local ret=$? | |
d61a01d4 | 116 | |
d1e71061 MT |
117 | if [ ${ret} -eq ${EXIT_OK} ]; then |
118 | log DEBUG "Successfully removed bonding device '${device}'" | |
119 | else | |
120 | log ERROR "Could not remove bonding device '${device}'" | |
121 | return ${EXIT_ERROR} | |
122 | fi | |
d61a01d4 | 123 | |
d1e71061 | 124 | return ${EXIT_OK} |
d61a01d4 MT |
125 | } |
126 | ||
711ffac1 MT |
127 | function bonding_get_mode() { |
128 | local device=${1} | |
d1e71061 | 129 | assert isset device |
711ffac1 MT |
130 | |
131 | local mode mode_num | |
132 | read mode mode_num < ${SYS_CLASS_NET}/${device}/bonding/mode | |
d1e71061 | 133 | print "${mode}" |
711ffac1 MT |
134 | } |
135 | ||
d61a01d4 | 136 | function bonding_enslave_device() { |
5bb2429a | 137 | local device=${1} |
d1e71061 MT |
138 | assert isset device |
139 | ||
5bb2429a | 140 | local slave=${2} |
d1e71061 MT |
141 | assert isset slave |
142 | ||
d61a01d4 MT |
143 | shift 2 |
144 | ||
d1e71061 MT |
145 | # Slave must be down to be enslaved. |
146 | device_set_down ${device} | |
147 | ||
148 | if device_is_up ${device}; then | |
149 | log ERROR "Cannot enslave '${slave}' because it cannot be set down." | |
150 | return ${EXIT_ERROR} | |
151 | fi | |
711ffac1 | 152 | |
d1e71061 MT |
153 | # Add it. |
154 | print "+${slave}" > ${SYS_CLASS_NET}/${device}/bonding/slaves | |
155 | local ret=$? | |
d61a01d4 | 156 | |
d1e71061 MT |
157 | if [ ${ret} -eq ${EXIT_OK} ]; then |
158 | log DEBUG "Successfully enslaved '${slave}' to '${device}'." | |
159 | else | |
160 | log ERROR "Could not enslave '${slave}' to '${device}'." | |
161 | return ${EXIT_ERROR} | |
162 | fi | |
163 | ||
164 | return ${EXIT_OK} | |
d61a01d4 | 165 | } |
711ffac1 MT |
166 | |
167 | function bonding_get_slaves() { | |
168 | local device=${1} | |
d1e71061 MT |
169 | assert isset device |
170 | shift | |
171 | ||
172 | local file="slaves" | |
173 | while [ $# -gt 0 ]; do | |
174 | case "${1}" in | |
175 | --active) | |
176 | file="active_slave" | |
177 | ;; | |
178 | *) | |
179 | error "Unrecognized argument: ${1}" | |
180 | return ${EXIT_ERROR} | |
181 | ;; | |
182 | esac | |
183 | shift | |
184 | done | |
711ffac1 | 185 | |
d1e71061 MT |
186 | fread ${SYS_CLASS_NET}/${device}/bonding/${file} |
187 | ||
188 | return ${EXIT_OK} | |
711ffac1 MT |
189 | } |
190 | ||
d1e71061 | 191 | function bonding_get_lacp_rate() { |
711ffac1 | 192 | local device=${1} |
d1e71061 | 193 | assert isset device |
711ffac1 | 194 | |
d1e71061 MT |
195 | local rate rateno |
196 | read -r rate rateno \ | |
197 | < ${SYS_CLASS_NET}/${device}/bonding/lacp_rate | |
711ffac1 | 198 | |
d1e71061 MT |
199 | print "${rate}" |
200 | return ${EXIT_OK} | |
201 | } | |
711ffac1 MT |
202 | |
203 | function bonding_get_miimon() { | |
204 | local device=${1} | |
d1e71061 | 205 | assert isset device |
711ffac1 | 206 | |
d1e71061 | 207 | fread ${SYS_CLASS_NET}/${device}/bonding/miimon |
711ffac1 MT |
208 | } |
209 | ||
210 | function bonding_set_miimon() { | |
211 | local device=${1} | |
d1e71061 | 212 | assert isset device |
711ffac1 | 213 | |
d1e71061 MT |
214 | local miimon=${2} |
215 | assert isset miimon | |
711ffac1 | 216 | |
d1e71061 | 217 | print "${miimon}" > ${SYS_CLASS_NET}/${device}/bonding/miimon |
711ffac1 MT |
218 | } |
219 | ||
220 | function bonding_slave_get_master() { | |
221 | local slave=${1} | |
711ffac1 | 222 | assert isset slave |
711ffac1 | 223 | |
d1e71061 MT |
224 | device_is_bonded ${slave} || return ${EXIT_ERROR} |
225 | ||
226 | local master=$(fread ${SYS_CLASS_NET}/${slave}/master/ifindex) | |
227 | if isset master; then | |
228 | device_ifindex_to_name ${master} | |
229 | return ${EXIT_OK} | |
230 | fi | |
711ffac1 MT |
231 | |
232 | return ${EXIT_ERROR} | |
233 | } |