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