]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-netdev-bond.c
util-lib: move string table stuff into its own string-table.[ch]
[thirdparty/systemd.git] / src / network / networkd-netdev-bond.c
CommitLineData
fe8ac65b
SS
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2014 Tom Gundersen <teg@jklm.no>
7 Copyright 2014 Susant Sahani
8
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
13
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
21***/
22
23#include <netinet/ether.h>
b621239e 24#include <linux/if_bonding.h>
fe8ac65b 25
1c4baffc 26#include "sd-netlink.h"
07630cea
LP
27
28#include "conf-parser.h"
fe8ac65b 29#include "missing.h"
07630cea 30#include "networkd-netdev-bond.h"
8b43440b
LP
31#include "string-util.h"
32#include "string-table.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
SS
270 if (r < 0)
271 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_ARP_VALIDATE attribute: %m");
81bd37a8
SS
272 }
273
274 if (b->primary_reselect != _NETDEV_BOND_PRIMARY_RESELECT_INVALID) {
1c4baffc 275 r = sd_netlink_message_append_u32(m, IFLA_BOND_ARP_ALL_TARGETS, b->primary_reselect);
a668086e
SS
276 if (r < 0)
277 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_ARP_ALL_TARGETS 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;
342 const char *word, *state;
343 size_t l;
344 int r;
345
346 assert(filename);
347 assert(lvalue);
348 assert(rvalue);
349 assert(data);
350
351 FOREACH_WORD_QUOTED(word, l, rvalue, state) {
352 _cleanup_free_ ArpIpTarget *buffer = NULL;
353 _cleanup_free_ char *n = NULL;
354 int f;
355
356 n = strndup(word, l);
357 if (!n)
358 return -ENOMEM;
359
360 buffer = new0(ArpIpTarget, 1);
361 if (!buffer)
362 return -ENOMEM;
363
364 r = in_addr_from_string_auto(n, &f, &buffer->ip);
365 if (r < 0) {
12ca818f 366 log_syntax(unit, LOG_ERR, filename, line, r, "Bond ARP ip target address is invalid, ignoring assignment: %s", n);
81bd37a8
SS
367 return 0;
368 }
369
370 if (f != AF_INET) {
12ca818f 371 log_syntax(unit, LOG_ERR, filename, line, 0, "Bond ARP ip target address is invalid, ignoring assignment: %s", n);
81bd37a8
SS
372 return 0;
373 }
374
375 LIST_PREPEND(arp_ip_target, b->arp_ip_targets, buffer);
376 b->n_arp_ip_targets ++;
377
378 buffer = NULL;
81bd37a8
SS
379 }
380
dd906398 381 if (b->n_arp_ip_targets > NETDEV_BOND_ARP_TARGETS_MAX)
12ca818f 382 log_syntax(unit, LOG_WARNING, filename, line, 0, "More than the maximum number of kernel-supported ARP ip targets specified: %d > %d", b->n_arp_ip_targets, NETDEV_BOND_ARP_TARGETS_MAX);
dd906398 383
81bd37a8
SS
384 return 0;
385}
386
387static void bond_done(NetDev *netdev) {
388 ArpIpTarget *t = NULL, *n = NULL;
ae185f48 389 Bond *b;
81bd37a8
SS
390
391 assert(netdev);
ae185f48
SS
392
393 b = BOND(netdev);
394
81bd37a8
SS
395 assert(b);
396
397 LIST_FOREACH_SAFE(arp_ip_target, t, n, b->arp_ip_targets)
398 free(t);
399
400 b->arp_ip_targets = NULL;
401}
402
aa9f1140 403static void bond_init(NetDev *netdev) {
ae185f48 404 Bond *b;
aa9f1140
TG
405
406 assert(netdev);
ae185f48
SS
407
408 b = BOND(netdev);
409
aa9f1140 410 assert(b);
fe8ac65b 411
aa9f1140 412 b->mode = _NETDEV_BOND_MODE_INVALID;
227cdf2c 413 b->xmit_hash_policy = _NETDEV_BOND_XMIT_HASH_POLICY_INVALID;
fb1021a2 414 b->lacp_rate = _NETDEV_BOND_LACP_RATE_INVALID;
81bd37a8
SS
415 b->ad_select = _NETDEV_BOND_AD_SELECT_INVALID;
416 b->fail_over_mac = _NETDEV_BOND_FAIL_OVER_MAC_INVALID;
417 b->arp_validate = _NETDEV_BOND_ARP_VALIDATE_INVALID;
418 b->arp_all_targets = _NETDEV_BOND_ARP_ALL_TARGETS_INVALID;
419 b->primary_reselect = _NETDEV_BOND_PRIMARY_RESELECT_INVALID;
420
421 b->all_slaves_active = false;
422
423 b->resend_igmp = RESEND_IGMP_DEFAULT;
424 b->packets_per_slave = PACKETS_PER_SLAVE_DEFAULT;
425 b->num_grat_arp = GRATUITOUS_ARP_DEFAULT;
426 b->lp_interval = LEARNING_PACKETS_INTERVAL_MIN_SEC;
427
428 LIST_HEAD_INIT(b->arp_ip_targets);
429 b->n_arp_ip_targets = 0;
fe8ac65b
SS
430}
431
3be1d7e0 432const NetDevVTable bond_vtable = {
aa9f1140
TG
433 .object_size = sizeof(Bond),
434 .init = bond_init,
81bd37a8 435 .done = bond_done,
aa9f1140 436 .sections = "Match\0NetDev\0Bond\0",
3be1d7e0 437 .fill_message_create = netdev_bond_fill_message_create,
aa9f1140 438 .create_type = NETDEV_CREATE_MASTER,
3be1d7e0 439};