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