]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-netdev-bond.c
Merge pull request #2495 from heftig/master
[thirdparty/systemd.git] / src / network / networkd-netdev-bond.c
CommitLineData
fe8ac65b
SS
1/***
2 This file is part of systemd.
3
4 Copyright 2014 Tom Gundersen <teg@jklm.no>
5 Copyright 2014 Susant Sahani
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19***/
20
21#include <netinet/ether.h>
b621239e 22#include <linux/if_bonding.h>
fe8ac65b 23
1c4baffc 24#include "sd-netlink.h"
07630cea 25
b5efdb8a 26#include "alloc-util.h"
07630cea 27#include "conf-parser.h"
fe8ac65b 28#include "missing.h"
07630cea 29#include "networkd-netdev-bond.h"
8b43440b 30#include "string-table.h"
cf0fbc49 31#include "string-util.h"
fe8ac65b 32
81bd37a8
SS
33/*
34 * Number of seconds between instances where the bonding
35 * driver sends learning packets to each slaves peer switch
36 */
37#define LEARNING_PACKETS_INTERVAL_MIN_SEC (1 * USEC_PER_SEC)
38#define LEARNING_PACKETS_INTERVAL_MAX_SEC (0x7fffffff * USEC_PER_SEC)
39
40/* Number of IGMP membership reports to be issued after
41 * a failover event.
42 */
43#define RESEND_IGMP_MIN 0
44#define RESEND_IGMP_MAX 255
45#define RESEND_IGMP_DEFAULT 1
46
47/*
48 * Number of packets to transmit through a slave before
49 * moving to the next one.
50 */
51#define PACKETS_PER_SLAVE_MIN 0
52#define PACKETS_PER_SLAVE_MAX 65535
53#define PACKETS_PER_SLAVE_DEFAULT 1
54
55/*
56 * Number of peer notifications (gratuitous ARPs and
57 * unsolicited IPv6 Neighbor Advertisements) to be issued after a
58 * failover event.
59 */
60#define GRATUITOUS_ARP_MIN 0
61#define GRATUITOUS_ARP_MAX 255
62#define GRATUITOUS_ARP_DEFAULT 1
63
fe8ac65b
SS
64static const char* const bond_mode_table[_NETDEV_BOND_MODE_MAX] = {
65 [NETDEV_BOND_MODE_BALANCE_RR] = "balance-rr",
66 [NETDEV_BOND_MODE_ACTIVE_BACKUP] = "active-backup",
67 [NETDEV_BOND_MODE_BALANCE_XOR] = "balance-xor",
68 [NETDEV_BOND_MODE_BROADCAST] = "broadcast",
69 [NETDEV_BOND_MODE_802_3AD] = "802.3ad",
70 [NETDEV_BOND_MODE_BALANCE_TLB] = "balance-tlb",
71 [NETDEV_BOND_MODE_BALANCE_ALB] = "balance-alb",
72};
73
74DEFINE_STRING_TABLE_LOOKUP(bond_mode, BondMode);
75DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_mode, bond_mode, BondMode, "Failed to parse bond mode");
76
227cdf2c
SS
77static const char* const bond_xmit_hash_policy_table[_NETDEV_BOND_XMIT_HASH_POLICY_MAX] = {
78 [NETDEV_BOND_XMIT_HASH_POLICY_LAYER2] = "layer2",
79 [NETDEV_BOND_XMIT_HASH_POLICY_LAYER34] = "layer3+4",
80 [NETDEV_BOND_XMIT_HASH_POLICY_LAYER23] = "layer2+3",
81 [NETDEV_BOND_XMIT_HASH_POLICY_ENCAP23] = "encap2+3",
82 [NETDEV_BOND_XMIT_HASH_POLICY_ENCAP34] = "encap3+4",
83};
84
85DEFINE_STRING_TABLE_LOOKUP(bond_xmit_hash_policy, BondXmitHashPolicy);
86DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_xmit_hash_policy,
87 bond_xmit_hash_policy,
88 BondXmitHashPolicy,
89 "Failed to parse bond transmit hash policy")
90
fb1021a2
SS
91static const char* const bond_lacp_rate_table[_NETDEV_BOND_LACP_RATE_MAX] = {
92 [NETDEV_BOND_LACP_RATE_SLOW] = "slow",
93 [NETDEV_BOND_LACP_RATE_FAST] = "fast",
94};
95
96DEFINE_STRING_TABLE_LOOKUP(bond_lacp_rate, BondLacpRate);
97DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_lacp_rate, bond_lacp_rate, BondLacpRate, "Failed to parse bond lacp rate")
98
81bd37a8
SS
99static const char* const bond_ad_select_table[_NETDEV_BOND_AD_SELECT_MAX] = {
100 [NETDEV_BOND_AD_SELECT_STABLE] = "stable",
101 [NETDEV_BOND_AD_SELECT_BANDWIDTH] = "bandwidth",
102 [NETDEV_BOND_AD_SELECT_COUNT] = "count",
103};
104
105DEFINE_STRING_TABLE_LOOKUP(bond_ad_select, BondAdSelect);
106DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_ad_select, bond_ad_select, BondAdSelect, "Failed to parse bond AD select");
107
108static const char* const bond_fail_over_mac_table[_NETDEV_BOND_FAIL_OVER_MAC_MAX] = {
109 [NETDEV_BOND_FAIL_OVER_MAC_NONE] = "none",
110 [NETDEV_BOND_FAIL_OVER_MAC_ACTIVE] = "active",
111 [NETDEV_BOND_FAIL_OVER_MAC_FOLLOW] = "follow",
112};
113
114DEFINE_STRING_TABLE_LOOKUP(bond_fail_over_mac, BondFailOverMac);
115DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_fail_over_mac, bond_fail_over_mac, BondFailOverMac, "Failed to parse bond fail over MAC");
116
117static const char *const bond_arp_validate_table[_NETDEV_BOND_ARP_VALIDATE_MAX] = {
118 [NETDEV_BOND_ARP_VALIDATE_NONE] = "none",
119 [NETDEV_BOND_ARP_VALIDATE_ACTIVE]= "active",
120 [NETDEV_BOND_ARP_VALIDATE_BACKUP]= "backup",
121 [NETDEV_BOND_ARP_VALIDATE_ALL]= "all",
122};
123
124DEFINE_STRING_TABLE_LOOKUP(bond_arp_validate, BondArpValidate);
125DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_arp_validate, bond_arp_validate, BondArpValidate, "Failed to parse bond arp validate");
126
127static const char *const bond_arp_all_targets_table[_NETDEV_BOND_ARP_ALL_TARGETS_MAX] = {
128 [NETDEV_BOND_ARP_ALL_TARGETS_ANY] = "any",
129 [NETDEV_BOND_ARP_ALL_TARGETS_ALL] = "all",
130};
131
132DEFINE_STRING_TABLE_LOOKUP(bond_arp_all_targets, BondArpAllTargets);
133DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_arp_all_targets, bond_arp_all_targets, BondArpAllTargets, "Failed to parse bond Arp all targets");
134
135static const char *bond_primary_reselect_table[_NETDEV_BOND_PRIMARY_RESELECT_MAX] = {
136 [NETDEV_BOND_PRIMARY_RESELECT_ALWAYS] = "always",
137 [NETDEV_BOND_PRIMARY_RESELECT_BETTER]= "better",
138 [NETDEV_BOND_PRIMARY_RESELECT_FAILURE]= "failure",
139};
140
141DEFINE_STRING_TABLE_LOOKUP(bond_primary_reselect, BondPrimaryReselect);
142DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_primary_reselect, bond_primary_reselect, BondPrimaryReselect, "Failed to parse bond primary reselect");
143
b621239e
TG
144static uint8_t bond_mode_to_kernel(BondMode mode) {
145 switch (mode) {
146 case NETDEV_BOND_MODE_BALANCE_RR:
147 return BOND_MODE_ROUNDROBIN;
148 case NETDEV_BOND_MODE_ACTIVE_BACKUP:
149 return BOND_MODE_ACTIVEBACKUP;
150 case NETDEV_BOND_MODE_BALANCE_XOR:
151 return BOND_MODE_XOR;
152 case NETDEV_BOND_MODE_BROADCAST:
153 return BOND_MODE_BROADCAST;
154 case NETDEV_BOND_MODE_802_3AD:
155 return BOND_MODE_8023AD;
156 case NETDEV_BOND_MODE_BALANCE_TLB:
157 return BOND_MODE_TLB;
158 case NETDEV_BOND_MODE_BALANCE_ALB:
159 return BOND_MODE_ALB;
160 default:
161 return (uint8_t) -1;
162 }
163}
164
227cdf2c
SS
165static uint8_t bond_xmit_hash_policy_to_kernel(BondXmitHashPolicy policy) {
166 switch (policy) {
167 case NETDEV_BOND_XMIT_HASH_POLICY_LAYER2:
168 return BOND_XMIT_POLICY_LAYER2;
169 case NETDEV_BOND_XMIT_HASH_POLICY_LAYER34:
170 return BOND_XMIT_POLICY_LAYER34;
171 case NETDEV_BOND_XMIT_HASH_POLICY_LAYER23:
172 return BOND_XMIT_POLICY_LAYER23;
173 case NETDEV_BOND_XMIT_HASH_POLICY_ENCAP23:
174 return BOND_XMIT_POLICY_ENCAP23;
175 case NETDEV_BOND_XMIT_HASH_POLICY_ENCAP34:
176 return BOND_XMIT_POLICY_ENCAP34;
177 default:
178 return (uint8_t) -1;
179 }
180}
181
1c4baffc 182static int netdev_bond_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
ae185f48 183 Bond *b;
81bd37a8
SS
184 ArpIpTarget *target = NULL;
185 int r, i = 0;
fe8ac65b 186
aa9f1140
TG
187 assert(netdev);
188 assert(!link);
fe8ac65b
SS
189 assert(m);
190
ae185f48
SS
191 b = BOND(netdev);
192
193 assert(b);
194
aa9f1140 195 if (b->mode != _NETDEV_BOND_MODE_INVALID) {
1c4baffc 196 r = sd_netlink_message_append_u8(m, IFLA_BOND_MODE,
aa9f1140 197 bond_mode_to_kernel(b->mode));
a668086e
SS
198 if (r < 0)
199 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_MODE attribute: %m");
fe8ac65b
SS
200 }
201
227cdf2c 202 if (b->xmit_hash_policy != _NETDEV_BOND_XMIT_HASH_POLICY_INVALID) {
1c4baffc 203 r = sd_netlink_message_append_u8(m, IFLA_BOND_XMIT_HASH_POLICY,
227cdf2c 204 bond_xmit_hash_policy_to_kernel(b->xmit_hash_policy));
a668086e
SS
205 if (r < 0)
206 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_XMIT_HASH_POLICY attribute: %m");
227cdf2c
SS
207 }
208
fb1021a2
SS
209 if (b->lacp_rate != _NETDEV_BOND_LACP_RATE_INVALID &&
210 b->mode == NETDEV_BOND_MODE_802_3AD) {
1c4baffc 211 r = sd_netlink_message_append_u8(m, IFLA_BOND_AD_LACP_RATE, b->lacp_rate );
ece174c5 212 if (r < 0)
a668086e 213 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_AD_LACP_RATE attribute: %m");
fb1021a2
SS
214 }
215
d9c52fa0 216 if (b->miimon != 0) {
1c4baffc 217 r = sd_netlink_message_append_u32(m, IFLA_BOND_MIIMON, b->miimon / USEC_PER_MSEC);
a668086e
SS
218 if (r < 0)
219 log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_BOND_MIIMON attribute: %m");
d9c52fa0
SS
220 }
221
222 if (b->downdelay != 0) {
1c4baffc 223 r = sd_netlink_message_append_u32(m, IFLA_BOND_DOWNDELAY, b->downdelay / USEC_PER_MSEC);
a668086e
SS
224 if (r < 0)
225 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_DOWNDELAY attribute: %m");
d9c52fa0
SS
226 }
227
228 if (b->updelay != 0) {
1c4baffc 229 r = sd_netlink_message_append_u32(m, IFLA_BOND_UPDELAY, b->updelay / USEC_PER_MSEC);
a668086e
SS
230 if (r < 0)
231 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_UPDELAY attribute: %m");
d9c52fa0
SS
232 }
233
81bd37a8 234 if (b->arp_interval != 0) {
1c4baffc 235 r = sd_netlink_message_append_u32(m, IFLA_BOND_ARP_INTERVAL, b->arp_interval / USEC_PER_MSEC);
a668086e
SS
236 if (r < 0)
237 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_ARP_INTERVAL attribute: %m");
238
239 if ((b->lp_interval >= LEARNING_PACKETS_INTERVAL_MIN_SEC) &&
240 (b->lp_interval <= LEARNING_PACKETS_INTERVAL_MAX_SEC)) {
1c4baffc 241 r = sd_netlink_message_append_u32(m, IFLA_BOND_LP_INTERVAL, b->lp_interval / USEC_PER_SEC);
a668086e
SS
242 if (r < 0)
243 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_LP_INTERVAL attribute: %m");
81bd37a8
SS
244 }
245 }
246
247 if (b->ad_select != _NETDEV_BOND_AD_SELECT_INVALID &&
76f0a567 248 b->mode == NETDEV_BOND_MODE_802_3AD) {
1c4baffc 249 r = sd_netlink_message_append_u8(m, IFLA_BOND_AD_SELECT, b->ad_select);
a668086e
SS
250 if (r < 0)
251 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_AD_SELECT attribute: %m");
81bd37a8
SS
252 }
253
254 if (b->fail_over_mac != _NETDEV_BOND_FAIL_OVER_MAC_INVALID &&
255 b->mode == NETDEV_BOND_MODE_ACTIVE_BACKUP) {
1c4baffc 256 r = sd_netlink_message_append_u8(m, IFLA_BOND_FAIL_OVER_MAC, b->fail_over_mac);
a668086e
SS
257 if (r < 0)
258 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_FAIL_OVER_MAC attribute: %m");
81bd37a8
SS
259 }
260
261 if (b->arp_validate != _NETDEV_BOND_ARP_VALIDATE_INVALID) {
1c4baffc 262 r = sd_netlink_message_append_u32(m, IFLA_BOND_ARP_VALIDATE, b->arp_validate);
a668086e
SS
263 if (r < 0)
264 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_ARP_VALIDATE attribute: %m");
81bd37a8
SS
265 }
266
267 if (b->arp_all_targets != _NETDEV_BOND_ARP_ALL_TARGETS_INVALID) {
1c4baffc 268 r = sd_netlink_message_append_u32(m, IFLA_BOND_ARP_ALL_TARGETS, b->arp_all_targets);
a668086e
SS
269 if (r < 0)
270 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_ARP_VALIDATE attribute: %m");
81bd37a8
SS
271 }
272
273 if (b->primary_reselect != _NETDEV_BOND_PRIMARY_RESELECT_INVALID) {
1c4baffc 274 r = sd_netlink_message_append_u32(m, IFLA_BOND_ARP_ALL_TARGETS, b->primary_reselect);
a668086e
SS
275 if (r < 0)
276 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_ARP_ALL_TARGETS attribute: %m");
81bd37a8
SS
277 }
278
279 if (b->resend_igmp <= RESEND_IGMP_MAX) {
1c4baffc 280 r = sd_netlink_message_append_u32(m, IFLA_BOND_RESEND_IGMP, b->resend_igmp);
a668086e
SS
281 if (r < 0)
282 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_RESEND_IGMP attribute: %m");
81bd37a8
SS
283 }
284
76f0a567
TG
285 if (b->packets_per_slave <= PACKETS_PER_SLAVE_MAX &&
286 b->mode == NETDEV_BOND_MODE_BALANCE_RR) {
1c4baffc 287 r = sd_netlink_message_append_u32(m, IFLA_BOND_PACKETS_PER_SLAVE, b->packets_per_slave);
a668086e
SS
288 if (r < 0)
289 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_PACKETS_PER_SLAVE attribute: %m");
81bd37a8
SS
290 }
291
292 if (b->num_grat_arp <= GRATUITOUS_ARP_MAX) {
1c4baffc 293 r = sd_netlink_message_append_u8(m, IFLA_BOND_NUM_PEER_NOTIF, b->num_grat_arp);
a668086e
SS
294 if (r < 0)
295 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_NUM_PEER_NOTIF attribute: %m");
81bd37a8
SS
296 }
297
298 if (b->min_links != 0) {
1c4baffc 299 r = sd_netlink_message_append_u32(m, IFLA_BOND_MIN_LINKS, b->min_links);
a668086e
SS
300 if (r < 0)
301 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_MIN_LINKS attribute: %m");
81bd37a8
SS
302 }
303
1c4baffc 304 r = sd_netlink_message_append_u8(m, IFLA_BOND_ALL_SLAVES_ACTIVE, b->all_slaves_active);
a668086e
SS
305 if (r < 0)
306 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_ALL_SLAVES_ACTIVE attribute: %m");
81bd37a8
SS
307
308 if (b->arp_interval > 0) {
309 if (b->n_arp_ip_targets > 0) {
310
1c4baffc 311 r = sd_netlink_message_open_container(m, IFLA_BOND_ARP_IP_TARGET);
a668086e
SS
312 if (r < 0)
313 return log_netdev_error_errno(netdev, r, "Could not open contaniner IFLA_BOND_ARP_IP_TARGET : %m");
81bd37a8
SS
314
315 LIST_FOREACH(arp_ip_target, target, b->arp_ip_targets) {
1c4baffc 316 r = sd_netlink_message_append_u32(m, i++, target->ip.in.s_addr);
a668086e
SS
317 if (r < 0)
318 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_ARP_ALL_TARGETS attribute: %m");
81bd37a8
SS
319 }
320
1c4baffc 321 r = sd_netlink_message_close_container(m);
a668086e
SS
322 if (r < 0)
323 return log_netdev_error_errno(netdev, r, "Could not close contaniner IFLA_BOND_ARP_IP_TARGET : %m");
81bd37a8
SS
324 }
325 }
326
aa9f1140
TG
327 return 0;
328}
fe8ac65b 329
81bd37a8
SS
330int config_parse_arp_ip_target_address(const char *unit,
331 const char *filename,
332 unsigned line,
333 const char *section,
334 unsigned section_line,
335 const char *lvalue,
336 int ltype,
337 const char *rvalue,
338 void *data,
339 void *userdata) {
340 Bond *b = userdata;
81bd37a8
SS
341 int r;
342
343 assert(filename);
344 assert(lvalue);
345 assert(rvalue);
346 assert(data);
347
022833c8 348 for (;;) {
81bd37a8
SS
349 _cleanup_free_ ArpIpTarget *buffer = NULL;
350 _cleanup_free_ char *n = NULL;
351 int f;
352
022833c8
SS
353 r = extract_first_word(&rvalue, &n, NULL, 0);
354 if (r < 0) {
355 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse Bond ARP ip target address, ignoring assignment: %s", rvalue);
356 return 0;
357 }
358
359 if (r == 0)
360 break;
81bd37a8
SS
361
362 buffer = new0(ArpIpTarget, 1);
363 if (!buffer)
364 return -ENOMEM;
365
366 r = in_addr_from_string_auto(n, &f, &buffer->ip);
367 if (r < 0) {
12ca818f 368 log_syntax(unit, LOG_ERR, filename, line, r, "Bond ARP ip target address is invalid, ignoring assignment: %s", n);
81bd37a8
SS
369 return 0;
370 }
371
372 if (f != AF_INET) {
12ca818f 373 log_syntax(unit, LOG_ERR, filename, line, 0, "Bond ARP ip target address is invalid, ignoring assignment: %s", n);
81bd37a8
SS
374 return 0;
375 }
376
377 LIST_PREPEND(arp_ip_target, b->arp_ip_targets, buffer);
378 b->n_arp_ip_targets ++;
379
380 buffer = NULL;
81bd37a8
SS
381 }
382
dd906398 383 if (b->n_arp_ip_targets > NETDEV_BOND_ARP_TARGETS_MAX)
022833c8
SS
384 log_syntax(unit, LOG_WARNING, filename, line, 0,
385 "More than the maximum number of kernel-supported ARP ip targets specified: %d > %d",
386 b->n_arp_ip_targets, NETDEV_BOND_ARP_TARGETS_MAX);
dd906398 387
81bd37a8
SS
388 return 0;
389}
390
391static void bond_done(NetDev *netdev) {
392 ArpIpTarget *t = NULL, *n = NULL;
ae185f48 393 Bond *b;
81bd37a8
SS
394
395 assert(netdev);
ae185f48
SS
396
397 b = BOND(netdev);
398
81bd37a8
SS
399 assert(b);
400
401 LIST_FOREACH_SAFE(arp_ip_target, t, n, b->arp_ip_targets)
402 free(t);
403
404 b->arp_ip_targets = NULL;
405}
406
aa9f1140 407static void bond_init(NetDev *netdev) {
ae185f48 408 Bond *b;
aa9f1140
TG
409
410 assert(netdev);
ae185f48
SS
411
412 b = BOND(netdev);
413
aa9f1140 414 assert(b);
fe8ac65b 415
aa9f1140 416 b->mode = _NETDEV_BOND_MODE_INVALID;
227cdf2c 417 b->xmit_hash_policy = _NETDEV_BOND_XMIT_HASH_POLICY_INVALID;
fb1021a2 418 b->lacp_rate = _NETDEV_BOND_LACP_RATE_INVALID;
81bd37a8
SS
419 b->ad_select = _NETDEV_BOND_AD_SELECT_INVALID;
420 b->fail_over_mac = _NETDEV_BOND_FAIL_OVER_MAC_INVALID;
421 b->arp_validate = _NETDEV_BOND_ARP_VALIDATE_INVALID;
422 b->arp_all_targets = _NETDEV_BOND_ARP_ALL_TARGETS_INVALID;
423 b->primary_reselect = _NETDEV_BOND_PRIMARY_RESELECT_INVALID;
424
425 b->all_slaves_active = false;
426
427 b->resend_igmp = RESEND_IGMP_DEFAULT;
428 b->packets_per_slave = PACKETS_PER_SLAVE_DEFAULT;
429 b->num_grat_arp = GRATUITOUS_ARP_DEFAULT;
430 b->lp_interval = LEARNING_PACKETS_INTERVAL_MIN_SEC;
431
432 LIST_HEAD_INIT(b->arp_ip_targets);
433 b->n_arp_ip_targets = 0;
fe8ac65b
SS
434}
435
3be1d7e0 436const NetDevVTable bond_vtable = {
aa9f1140
TG
437 .object_size = sizeof(Bond),
438 .init = bond_init,
81bd37a8 439 .done = bond_done,
aa9f1140 440 .sections = "Match\0NetDev\0Bond\0",
3be1d7e0 441 .fill_message_create = netdev_bond_fill_message_create,
aa9f1140 442 .create_type = NETDEV_CREATE_MASTER,
3be1d7e0 443};