]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/netdev/bond.c
network: drop bond_mode_to_kernel() and bond_xmit_hash_policy_to_kernel()
[thirdparty/systemd.git] / src / network / netdev / bond.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
fe8ac65b 2
1c4baffc 3#include "sd-netlink.h"
07630cea 4
b5efdb8a 5#include "alloc-util.h"
f2000933 6#include "bond.h"
07630cea 7#include "conf-parser.h"
99f68ef0 8#include "ether-addr-util.h"
634f0f98 9#include "extract-word.h"
8b43440b 10#include "string-table.h"
cf0fbc49 11#include "string-util.h"
fe8ac65b 12
81bd37a8
SS
13/*
14 * Number of seconds between instances where the bonding
15 * driver sends learning packets to each slaves peer switch
16 */
17#define LEARNING_PACKETS_INTERVAL_MIN_SEC (1 * USEC_PER_SEC)
18#define LEARNING_PACKETS_INTERVAL_MAX_SEC (0x7fffffff * USEC_PER_SEC)
19
20/* Number of IGMP membership reports to be issued after
21 * a failover event.
22 */
23#define RESEND_IGMP_MIN 0
24#define RESEND_IGMP_MAX 255
25#define RESEND_IGMP_DEFAULT 1
26
27/*
28 * Number of packets to transmit through a slave before
29 * moving to the next one.
30 */
31#define PACKETS_PER_SLAVE_MIN 0
32#define PACKETS_PER_SLAVE_MAX 65535
33#define PACKETS_PER_SLAVE_DEFAULT 1
34
35/*
36 * Number of peer notifications (gratuitous ARPs and
37 * unsolicited IPv6 Neighbor Advertisements) to be issued after a
38 * failover event.
39 */
40#define GRATUITOUS_ARP_MIN 0
41#define GRATUITOUS_ARP_MAX 255
42#define GRATUITOUS_ARP_DEFAULT 1
43
fe8ac65b
SS
44static const char* const bond_mode_table[_NETDEV_BOND_MODE_MAX] = {
45 [NETDEV_BOND_MODE_BALANCE_RR] = "balance-rr",
46 [NETDEV_BOND_MODE_ACTIVE_BACKUP] = "active-backup",
47 [NETDEV_BOND_MODE_BALANCE_XOR] = "balance-xor",
48 [NETDEV_BOND_MODE_BROADCAST] = "broadcast",
49 [NETDEV_BOND_MODE_802_3AD] = "802.3ad",
50 [NETDEV_BOND_MODE_BALANCE_TLB] = "balance-tlb",
51 [NETDEV_BOND_MODE_BALANCE_ALB] = "balance-alb",
52};
53
54DEFINE_STRING_TABLE_LOOKUP(bond_mode, BondMode);
55DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_mode, bond_mode, BondMode, "Failed to parse bond mode");
56
227cdf2c
SS
57static const char* const bond_xmit_hash_policy_table[_NETDEV_BOND_XMIT_HASH_POLICY_MAX] = {
58 [NETDEV_BOND_XMIT_HASH_POLICY_LAYER2] = "layer2",
59 [NETDEV_BOND_XMIT_HASH_POLICY_LAYER34] = "layer3+4",
60 [NETDEV_BOND_XMIT_HASH_POLICY_LAYER23] = "layer2+3",
61 [NETDEV_BOND_XMIT_HASH_POLICY_ENCAP23] = "encap2+3",
62 [NETDEV_BOND_XMIT_HASH_POLICY_ENCAP34] = "encap3+4",
63};
64
65DEFINE_STRING_TABLE_LOOKUP(bond_xmit_hash_policy, BondXmitHashPolicy);
66DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_xmit_hash_policy,
67 bond_xmit_hash_policy,
68 BondXmitHashPolicy,
69 "Failed to parse bond transmit hash policy")
70
fb1021a2
SS
71static const char* const bond_lacp_rate_table[_NETDEV_BOND_LACP_RATE_MAX] = {
72 [NETDEV_BOND_LACP_RATE_SLOW] = "slow",
73 [NETDEV_BOND_LACP_RATE_FAST] = "fast",
74};
75
76DEFINE_STRING_TABLE_LOOKUP(bond_lacp_rate, BondLacpRate);
77DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_lacp_rate, bond_lacp_rate, BondLacpRate, "Failed to parse bond lacp rate")
78
81bd37a8
SS
79static const char* const bond_ad_select_table[_NETDEV_BOND_AD_SELECT_MAX] = {
80 [NETDEV_BOND_AD_SELECT_STABLE] = "stable",
81 [NETDEV_BOND_AD_SELECT_BANDWIDTH] = "bandwidth",
82 [NETDEV_BOND_AD_SELECT_COUNT] = "count",
83};
84
85DEFINE_STRING_TABLE_LOOKUP(bond_ad_select, BondAdSelect);
86DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_ad_select, bond_ad_select, BondAdSelect, "Failed to parse bond AD select");
87
88static const char* const bond_fail_over_mac_table[_NETDEV_BOND_FAIL_OVER_MAC_MAX] = {
89 [NETDEV_BOND_FAIL_OVER_MAC_NONE] = "none",
90 [NETDEV_BOND_FAIL_OVER_MAC_ACTIVE] = "active",
91 [NETDEV_BOND_FAIL_OVER_MAC_FOLLOW] = "follow",
92};
93
94DEFINE_STRING_TABLE_LOOKUP(bond_fail_over_mac, BondFailOverMac);
95DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_fail_over_mac, bond_fail_over_mac, BondFailOverMac, "Failed to parse bond fail over MAC");
96
97static const char *const bond_arp_validate_table[_NETDEV_BOND_ARP_VALIDATE_MAX] = {
98 [NETDEV_BOND_ARP_VALIDATE_NONE] = "none",
99 [NETDEV_BOND_ARP_VALIDATE_ACTIVE]= "active",
100 [NETDEV_BOND_ARP_VALIDATE_BACKUP]= "backup",
101 [NETDEV_BOND_ARP_VALIDATE_ALL]= "all",
102};
103
104DEFINE_STRING_TABLE_LOOKUP(bond_arp_validate, BondArpValidate);
105DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_arp_validate, bond_arp_validate, BondArpValidate, "Failed to parse bond arp validate");
106
107static const char *const bond_arp_all_targets_table[_NETDEV_BOND_ARP_ALL_TARGETS_MAX] = {
108 [NETDEV_BOND_ARP_ALL_TARGETS_ANY] = "any",
109 [NETDEV_BOND_ARP_ALL_TARGETS_ALL] = "all",
110};
111
112DEFINE_STRING_TABLE_LOOKUP(bond_arp_all_targets, BondArpAllTargets);
113DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_arp_all_targets, bond_arp_all_targets, BondArpAllTargets, "Failed to parse bond Arp all targets");
114
b82f71c7 115static const char *const bond_primary_reselect_table[_NETDEV_BOND_PRIMARY_RESELECT_MAX] = {
81bd37a8
SS
116 [NETDEV_BOND_PRIMARY_RESELECT_ALWAYS] = "always",
117 [NETDEV_BOND_PRIMARY_RESELECT_BETTER]= "better",
118 [NETDEV_BOND_PRIMARY_RESELECT_FAILURE]= "failure",
119};
120
121DEFINE_STRING_TABLE_LOOKUP(bond_primary_reselect, BondPrimaryReselect);
122DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_primary_reselect, bond_primary_reselect, BondPrimaryReselect, "Failed to parse bond primary reselect");
123
1c4baffc 124static int netdev_bond_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
ae185f48 125 Bond *b;
81bd37a8
SS
126 ArpIpTarget *target = NULL;
127 int r, i = 0;
fe8ac65b 128
aa9f1140
TG
129 assert(netdev);
130 assert(!link);
fe8ac65b
SS
131 assert(m);
132
ae185f48
SS
133 b = BOND(netdev);
134
135 assert(b);
136
aa9f1140 137 if (b->mode != _NETDEV_BOND_MODE_INVALID) {
f2000933 138 r = sd_netlink_message_append_u8(m, IFLA_BOND_MODE, b->mode);
a668086e
SS
139 if (r < 0)
140 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_MODE attribute: %m");
fe8ac65b
SS
141 }
142
227cdf2c 143 if (b->xmit_hash_policy != _NETDEV_BOND_XMIT_HASH_POLICY_INVALID) {
f2000933 144 r = sd_netlink_message_append_u8(m, IFLA_BOND_XMIT_HASH_POLICY, b->xmit_hash_policy);
a668086e
SS
145 if (r < 0)
146 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_XMIT_HASH_POLICY attribute: %m");
227cdf2c
SS
147 }
148
fb1021a2
SS
149 if (b->lacp_rate != _NETDEV_BOND_LACP_RATE_INVALID &&
150 b->mode == NETDEV_BOND_MODE_802_3AD) {
3f7cc080 151 r = sd_netlink_message_append_u8(m, IFLA_BOND_AD_LACP_RATE, b->lacp_rate);
ece174c5 152 if (r < 0)
a668086e 153 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_AD_LACP_RATE attribute: %m");
fb1021a2
SS
154 }
155
d9c52fa0 156 if (b->miimon != 0) {
1c4baffc 157 r = sd_netlink_message_append_u32(m, IFLA_BOND_MIIMON, b->miimon / USEC_PER_MSEC);
a668086e
SS
158 if (r < 0)
159 log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_BOND_MIIMON attribute: %m");
d9c52fa0
SS
160 }
161
162 if (b->downdelay != 0) {
1c4baffc 163 r = sd_netlink_message_append_u32(m, IFLA_BOND_DOWNDELAY, b->downdelay / USEC_PER_MSEC);
a668086e
SS
164 if (r < 0)
165 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_DOWNDELAY attribute: %m");
d9c52fa0
SS
166 }
167
168 if (b->updelay != 0) {
1c4baffc 169 r = sd_netlink_message_append_u32(m, IFLA_BOND_UPDELAY, b->updelay / USEC_PER_MSEC);
a668086e
SS
170 if (r < 0)
171 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_UPDELAY attribute: %m");
d9c52fa0
SS
172 }
173
81bd37a8 174 if (b->arp_interval != 0) {
1c4baffc 175 r = sd_netlink_message_append_u32(m, IFLA_BOND_ARP_INTERVAL, b->arp_interval / USEC_PER_MSEC);
a668086e
SS
176 if (r < 0)
177 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_ARP_INTERVAL attribute: %m");
178
3f7cc080
YW
179 if (b->lp_interval >= LEARNING_PACKETS_INTERVAL_MIN_SEC &&
180 b->lp_interval <= LEARNING_PACKETS_INTERVAL_MAX_SEC) {
1c4baffc 181 r = sd_netlink_message_append_u32(m, IFLA_BOND_LP_INTERVAL, b->lp_interval / USEC_PER_SEC);
a668086e
SS
182 if (r < 0)
183 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_LP_INTERVAL attribute: %m");
81bd37a8
SS
184 }
185 }
186
187 if (b->ad_select != _NETDEV_BOND_AD_SELECT_INVALID &&
76f0a567 188 b->mode == NETDEV_BOND_MODE_802_3AD) {
1c4baffc 189 r = sd_netlink_message_append_u8(m, IFLA_BOND_AD_SELECT, b->ad_select);
a668086e
SS
190 if (r < 0)
191 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_AD_SELECT attribute: %m");
81bd37a8
SS
192 }
193
194 if (b->fail_over_mac != _NETDEV_BOND_FAIL_OVER_MAC_INVALID &&
195 b->mode == NETDEV_BOND_MODE_ACTIVE_BACKUP) {
1c4baffc 196 r = sd_netlink_message_append_u8(m, IFLA_BOND_FAIL_OVER_MAC, b->fail_over_mac);
a668086e
SS
197 if (r < 0)
198 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_FAIL_OVER_MAC attribute: %m");
81bd37a8
SS
199 }
200
201 if (b->arp_validate != _NETDEV_BOND_ARP_VALIDATE_INVALID) {
1c4baffc 202 r = sd_netlink_message_append_u32(m, IFLA_BOND_ARP_VALIDATE, b->arp_validate);
a668086e
SS
203 if (r < 0)
204 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_ARP_VALIDATE attribute: %m");
81bd37a8
SS
205 }
206
207 if (b->arp_all_targets != _NETDEV_BOND_ARP_ALL_TARGETS_INVALID) {
1c4baffc 208 r = sd_netlink_message_append_u32(m, IFLA_BOND_ARP_ALL_TARGETS, b->arp_all_targets);
a668086e 209 if (r < 0)
e59ace18 210 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_ARP_ALL_TARGETS attribute: %m");
81bd37a8
SS
211 }
212
213 if (b->primary_reselect != _NETDEV_BOND_PRIMARY_RESELECT_INVALID) {
e59ace18 214 r = sd_netlink_message_append_u8(m, IFLA_BOND_PRIMARY_RESELECT, b->primary_reselect);
a668086e 215 if (r < 0)
e59ace18 216 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_PRIMARY_RESELECT attribute: %m");
81bd37a8
SS
217 }
218
219 if (b->resend_igmp <= RESEND_IGMP_MAX) {
1c4baffc 220 r = sd_netlink_message_append_u32(m, IFLA_BOND_RESEND_IGMP, b->resend_igmp);
a668086e
SS
221 if (r < 0)
222 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_RESEND_IGMP attribute: %m");
81bd37a8
SS
223 }
224
76f0a567
TG
225 if (b->packets_per_slave <= PACKETS_PER_SLAVE_MAX &&
226 b->mode == NETDEV_BOND_MODE_BALANCE_RR) {
1c4baffc 227 r = sd_netlink_message_append_u32(m, IFLA_BOND_PACKETS_PER_SLAVE, b->packets_per_slave);
a668086e
SS
228 if (r < 0)
229 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_PACKETS_PER_SLAVE attribute: %m");
81bd37a8
SS
230 }
231
232 if (b->num_grat_arp <= GRATUITOUS_ARP_MAX) {
1c4baffc 233 r = sd_netlink_message_append_u8(m, IFLA_BOND_NUM_PEER_NOTIF, b->num_grat_arp);
a668086e
SS
234 if (r < 0)
235 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_NUM_PEER_NOTIF attribute: %m");
81bd37a8
SS
236 }
237
238 if (b->min_links != 0) {
1c4baffc 239 r = sd_netlink_message_append_u32(m, IFLA_BOND_MIN_LINKS, b->min_links);
a668086e
SS
240 if (r < 0)
241 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_MIN_LINKS attribute: %m");
81bd37a8
SS
242 }
243
99f68ef0
TJ
244 if (b->ad_actor_sys_prio != 0) {
245 r = sd_netlink_message_append_u16(m, IFLA_BOND_AD_ACTOR_SYS_PRIO, b->ad_actor_sys_prio);
246 if (r < 0)
247 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_AD_ACTOR_SYS_PRIO attribute: %m");
248 }
249
250 if (b->ad_user_port_key != 0) {
251 r = sd_netlink_message_append_u16(m, IFLA_BOND_AD_USER_PORT_KEY, b->ad_user_port_key);
252 if (r < 0)
253 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_AD_USER_PORT_KEY attribute: %m");
254 }
255
256 if (b->ad_actor_system) {
257 r = sd_netlink_message_append_ether_addr(m, IFLA_BOND_AD_ACTOR_SYSTEM, b->ad_actor_system);
258 if (r < 0)
259 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_AD_ACTOR_SYSTEM attribute: %m");
260 }
261
1c4baffc 262 r = sd_netlink_message_append_u8(m, IFLA_BOND_ALL_SLAVES_ACTIVE, b->all_slaves_active);
a668086e
SS
263 if (r < 0)
264 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_ALL_SLAVES_ACTIVE attribute: %m");
81bd37a8 265
fde60a42
SS
266 if (b->tlb_dynamic_lb >= 0) {
267 r = sd_netlink_message_append_u8(m, IFLA_BOND_TLB_DYNAMIC_LB, b->tlb_dynamic_lb);
268 if (r < 0)
269 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_TLB_DYNAMIC_LB attribute: %m");
270 }
271
3f7cc080
YW
272 if (b->arp_interval > 0 && b->n_arp_ip_targets > 0) {
273 r = sd_netlink_message_open_container(m, IFLA_BOND_ARP_IP_TARGET);
274 if (r < 0)
275 return log_netdev_error_errno(netdev, r, "Could not open contaniner IFLA_BOND_ARP_IP_TARGET : %m");
81bd37a8 276
3f7cc080
YW
277 LIST_FOREACH(arp_ip_target, target, b->arp_ip_targets) {
278 r = sd_netlink_message_append_u32(m, i++, target->ip.in.s_addr);
a668086e 279 if (r < 0)
3f7cc080 280 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_ARP_ALL_TARGETS attribute: %m");
81bd37a8 281 }
3f7cc080
YW
282
283 r = sd_netlink_message_close_container(m);
284 if (r < 0)
285 return log_netdev_error_errno(netdev, r, "Could not close contaniner IFLA_BOND_ARP_IP_TARGET : %m");
81bd37a8
SS
286 }
287
aa9f1140
TG
288 return 0;
289}
fe8ac65b 290
81bd37a8
SS
291int config_parse_arp_ip_target_address(const char *unit,
292 const char *filename,
293 unsigned line,
294 const char *section,
295 unsigned section_line,
296 const char *lvalue,
297 int ltype,
298 const char *rvalue,
299 void *data,
300 void *userdata) {
301 Bond *b = userdata;
81bd37a8
SS
302 int r;
303
304 assert(filename);
305 assert(lvalue);
306 assert(rvalue);
307 assert(data);
308
022833c8 309 for (;;) {
81bd37a8
SS
310 _cleanup_free_ ArpIpTarget *buffer = NULL;
311 _cleanup_free_ char *n = NULL;
312 int f;
313
022833c8
SS
314 r = extract_first_word(&rvalue, &n, NULL, 0);
315 if (r < 0) {
316 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse Bond ARP ip target address, ignoring assignment: %s", rvalue);
317 return 0;
318 }
319
320 if (r == 0)
321 break;
81bd37a8
SS
322
323 buffer = new0(ArpIpTarget, 1);
324 if (!buffer)
325 return -ENOMEM;
326
327 r = in_addr_from_string_auto(n, &f, &buffer->ip);
328 if (r < 0) {
12ca818f 329 log_syntax(unit, LOG_ERR, filename, line, r, "Bond ARP ip target address is invalid, ignoring assignment: %s", n);
81bd37a8
SS
330 return 0;
331 }
332
333 if (f != AF_INET) {
12ca818f 334 log_syntax(unit, LOG_ERR, filename, line, 0, "Bond ARP ip target address is invalid, ignoring assignment: %s", n);
81bd37a8
SS
335 return 0;
336 }
337
1176b054 338 LIST_PREPEND(arp_ip_target, b->arp_ip_targets, TAKE_PTR(buffer));
313cefa1 339 b->n_arp_ip_targets++;
81bd37a8
SS
340 }
341
dd906398 342 if (b->n_arp_ip_targets > NETDEV_BOND_ARP_TARGETS_MAX)
022833c8
SS
343 log_syntax(unit, LOG_WARNING, filename, line, 0,
344 "More than the maximum number of kernel-supported ARP ip targets specified: %d > %d",
345 b->n_arp_ip_targets, NETDEV_BOND_ARP_TARGETS_MAX);
dd906398 346
81bd37a8
SS
347 return 0;
348}
349
99f68ef0
TJ
350int config_parse_ad_actor_sys_prio(const char *unit,
351 const char *filename,
352 unsigned line,
353 const char *section,
354 unsigned section_line,
355 const char *lvalue,
356 int ltype,
357 const char *rvalue,
358 void *data,
359 void *userdata) {
360 Bond *b = userdata;
361 uint16_t v;
362 int r;
363
364 assert(filename);
365 assert(lvalue);
366 assert(rvalue);
367 assert(data);
368
369 r = safe_atou16(rvalue, &v);
370 if (r < 0) {
371 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse actor system priority '%s', ignoring: %m", rvalue);
372 return 0;
373 }
374
375 if (v == 0) {
db688b7e 376 log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse actor system priority '%s'. Range is [1,65535], ignoring.", rvalue);
99f68ef0
TJ
377 return 0;
378 }
379
380 b->ad_actor_sys_prio = v;
381
382 return 0;
383}
384
385int config_parse_ad_user_port_key(const char *unit,
386 const char *filename,
387 unsigned line,
388 const char *section,
389 unsigned section_line,
390 const char *lvalue,
391 int ltype,
392 const char *rvalue,
393 void *data,
394 void *userdata) {
395 Bond *b = userdata;
396 uint16_t v;
397 int r;
398
399 assert(filename);
400 assert(lvalue);
401 assert(rvalue);
402 assert(data);
403
404 r = safe_atou16(rvalue, &v);
405 if (r < 0) {
406 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse user port key '%s', ignoring: %m", rvalue);
407 return 0;
408 }
409
410 if (v > 1023) {
db688b7e 411 log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse user port key '%s'. Range is [0,1023], ignoring.", rvalue);
99f68ef0
TJ
412 return 0;
413 }
414
415 b->ad_user_port_key = v;
416
417 return 0;
418}
419
420int config_parse_ad_actor_system(const char *unit,
421 const char *filename,
422 unsigned line,
423 const char *section,
424 unsigned section_line,
425 const char *lvalue,
426 int ltype,
427 const char *rvalue,
428 void *data,
429 void *userdata) {
430 Bond *b = userdata;
431 _cleanup_free_ struct ether_addr *n = NULL;
432 int r;
433
434 assert(filename);
435 assert(lvalue);
436 assert(rvalue);
437 assert(data);
438
439 n = new0(struct ether_addr, 1);
440 if (!n)
441 return log_oom();
442
443 r = ether_addr_from_string(rvalue, n);
444 if (r < 0) {
445 log_syntax(unit, LOG_ERR, filename, line, r, "Not a valid MAC address %s. Ignoring assignment: %m", rvalue);
446 return 0;
447 }
448
449 if (ether_addr_is_null(n) || (n->ether_addr_octet[0] & 0x01)) {
db688b7e 450 log_syntax(unit, LOG_ERR, filename, line, 0, "Not a valid MAC address %s, can not be null or multicast. Ignoring assignment.", rvalue);
99f68ef0
TJ
451 return 0;
452 }
453
454 free_and_replace(b->ad_actor_system, n);
455
456 return 0;
457}
458
81bd37a8
SS
459static void bond_done(NetDev *netdev) {
460 ArpIpTarget *t = NULL, *n = NULL;
ae185f48 461 Bond *b;
81bd37a8
SS
462
463 assert(netdev);
ae185f48
SS
464
465 b = BOND(netdev);
466
81bd37a8
SS
467 assert(b);
468
99f68ef0
TJ
469 free(b->ad_actor_system);
470
81bd37a8
SS
471 LIST_FOREACH_SAFE(arp_ip_target, t, n, b->arp_ip_targets)
472 free(t);
473
474 b->arp_ip_targets = NULL;
475}
476
aa9f1140 477static void bond_init(NetDev *netdev) {
ae185f48 478 Bond *b;
aa9f1140
TG
479
480 assert(netdev);
ae185f48
SS
481
482 b = BOND(netdev);
483
aa9f1140 484 assert(b);
fe8ac65b 485
aa9f1140 486 b->mode = _NETDEV_BOND_MODE_INVALID;
227cdf2c 487 b->xmit_hash_policy = _NETDEV_BOND_XMIT_HASH_POLICY_INVALID;
fb1021a2 488 b->lacp_rate = _NETDEV_BOND_LACP_RATE_INVALID;
81bd37a8
SS
489 b->ad_select = _NETDEV_BOND_AD_SELECT_INVALID;
490 b->fail_over_mac = _NETDEV_BOND_FAIL_OVER_MAC_INVALID;
491 b->arp_validate = _NETDEV_BOND_ARP_VALIDATE_INVALID;
492 b->arp_all_targets = _NETDEV_BOND_ARP_ALL_TARGETS_INVALID;
493 b->primary_reselect = _NETDEV_BOND_PRIMARY_RESELECT_INVALID;
494
495 b->all_slaves_active = false;
fde60a42 496 b->tlb_dynamic_lb = -1;
81bd37a8
SS
497
498 b->resend_igmp = RESEND_IGMP_DEFAULT;
499 b->packets_per_slave = PACKETS_PER_SLAVE_DEFAULT;
500 b->num_grat_arp = GRATUITOUS_ARP_DEFAULT;
501 b->lp_interval = LEARNING_PACKETS_INTERVAL_MIN_SEC;
502
503 LIST_HEAD_INIT(b->arp_ip_targets);
504 b->n_arp_ip_targets = 0;
fe8ac65b
SS
505}
506
3be1d7e0 507const NetDevVTable bond_vtable = {
aa9f1140
TG
508 .object_size = sizeof(Bond),
509 .init = bond_init,
81bd37a8 510 .done = bond_done,
aa9f1140 511 .sections = "Match\0NetDev\0Bond\0",
3be1d7e0 512 .fill_message_create = netdev_bond_fill_message_create,
aa9f1140 513 .create_type = NETDEV_CREATE_MASTER,
3be1d7e0 514};