Coverage Report

Created: 2019-06-19 13:33

/src/systemd/src/network/netdev/bond.c
Line
Count
Source (jump to first uncovered line)
1
/* SPDX-License-Identifier: LGPL-2.1+ */
2
3
#include "sd-netlink.h"
4
5
#include "alloc-util.h"
6
#include "bond.h"
7
#include "conf-parser.h"
8
#include "ether-addr-util.h"
9
#include "extract-word.h"
10
#include "netlink-util.h"
11
#include "networkd-manager.h"
12
#include "string-table.h"
13
#include "string-util.h"
14
15
/*
16
 * Number of seconds between instances where the bonding
17
 * driver sends learning packets to each slaves peer switch
18
 */
19
1.15k
#define LEARNING_PACKETS_INTERVAL_MIN_SEC       (1 * USEC_PER_SEC)
20
0
#define LEARNING_PACKETS_INTERVAL_MAX_SEC       (0x7fffffff * USEC_PER_SEC)
21
22
/* Number of IGMP membership reports to be issued after
23
 * a failover event.
24
 */
25
#define RESEND_IGMP_MIN           0
26
297
#define RESEND_IGMP_MAX           255
27
1.15k
#define RESEND_IGMP_DEFAULT       1
28
29
/*
30
 * Number of packets to transmit through a slave before
31
 * moving to the next one.
32
 */
33
#define PACKETS_PER_SLAVE_MIN     0
34
594
#define PACKETS_PER_SLAVE_MAX     65535
35
1.15k
#define PACKETS_PER_SLAVE_DEFAULT 1
36
37
/*
38
 * Number of peer notifications (gratuitous ARPs and
39
 * unsolicited IPv6 Neighbor Advertisements) to be issued after a
40
 * failover event.
41
 */
42
#define GRATUITOUS_ARP_MIN        0
43
297
#define GRATUITOUS_ARP_MAX        255
44
1.15k
#define GRATUITOUS_ARP_DEFAULT    1
45
46
static const char* const bond_mode_table[_NETDEV_BOND_MODE_MAX] = {
47
        [NETDEV_BOND_MODE_BALANCE_RR] = "balance-rr",
48
        [NETDEV_BOND_MODE_ACTIVE_BACKUP] = "active-backup",
49
        [NETDEV_BOND_MODE_BALANCE_XOR] = "balance-xor",
50
        [NETDEV_BOND_MODE_BROADCAST] = "broadcast",
51
        [NETDEV_BOND_MODE_802_3AD] = "802.3ad",
52
        [NETDEV_BOND_MODE_BALANCE_TLB] = "balance-tlb",
53
        [NETDEV_BOND_MODE_BALANCE_ALB] = "balance-alb",
54
};
55
56
DEFINE_STRING_TABLE_LOOKUP(bond_mode, BondMode);
57
DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_mode, bond_mode, BondMode, "Failed to parse bond mode");
58
59
static const char* const bond_xmit_hash_policy_table[_NETDEV_BOND_XMIT_HASH_POLICY_MAX] = {
60
        [NETDEV_BOND_XMIT_HASH_POLICY_LAYER2] = "layer2",
61
        [NETDEV_BOND_XMIT_HASH_POLICY_LAYER34] = "layer3+4",
62
        [NETDEV_BOND_XMIT_HASH_POLICY_LAYER23] = "layer2+3",
63
        [NETDEV_BOND_XMIT_HASH_POLICY_ENCAP23] = "encap2+3",
64
        [NETDEV_BOND_XMIT_HASH_POLICY_ENCAP34] = "encap3+4",
65
};
66
67
DEFINE_STRING_TABLE_LOOKUP(bond_xmit_hash_policy, BondXmitHashPolicy);
68
DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_xmit_hash_policy,
69
                         bond_xmit_hash_policy,
70
                         BondXmitHashPolicy,
71
                         "Failed to parse bond transmit hash policy")
72
73
static const char* const bond_lacp_rate_table[_NETDEV_BOND_LACP_RATE_MAX] = {
74
        [NETDEV_BOND_LACP_RATE_SLOW] = "slow",
75
        [NETDEV_BOND_LACP_RATE_FAST] = "fast",
76
};
77
78
DEFINE_STRING_TABLE_LOOKUP(bond_lacp_rate, BondLacpRate);
79
DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_lacp_rate, bond_lacp_rate, BondLacpRate, "Failed to parse bond lacp rate")
80
81
static const char* const bond_ad_select_table[_NETDEV_BOND_AD_SELECT_MAX] = {
82
        [NETDEV_BOND_AD_SELECT_STABLE] = "stable",
83
        [NETDEV_BOND_AD_SELECT_BANDWIDTH] = "bandwidth",
84
        [NETDEV_BOND_AD_SELECT_COUNT] = "count",
85
};
86
87
DEFINE_STRING_TABLE_LOOKUP(bond_ad_select, BondAdSelect);
88
DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_ad_select, bond_ad_select, BondAdSelect, "Failed to parse bond AD select");
89
90
static const char* const bond_fail_over_mac_table[_NETDEV_BOND_FAIL_OVER_MAC_MAX] = {
91
        [NETDEV_BOND_FAIL_OVER_MAC_NONE] = "none",
92
        [NETDEV_BOND_FAIL_OVER_MAC_ACTIVE] = "active",
93
        [NETDEV_BOND_FAIL_OVER_MAC_FOLLOW] = "follow",
94
};
95
96
DEFINE_STRING_TABLE_LOOKUP(bond_fail_over_mac, BondFailOverMac);
97
DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_fail_over_mac, bond_fail_over_mac, BondFailOverMac, "Failed to parse bond fail over MAC");
98
99
static const char *const bond_arp_validate_table[_NETDEV_BOND_ARP_VALIDATE_MAX] = {
100
        [NETDEV_BOND_ARP_VALIDATE_NONE] = "none",
101
        [NETDEV_BOND_ARP_VALIDATE_ACTIVE]= "active",
102
        [NETDEV_BOND_ARP_VALIDATE_BACKUP]= "backup",
103
        [NETDEV_BOND_ARP_VALIDATE_ALL]= "all",
104
};
105
106
DEFINE_STRING_TABLE_LOOKUP(bond_arp_validate, BondArpValidate);
107
DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_arp_validate, bond_arp_validate, BondArpValidate, "Failed to parse bond arp validate");
108
109
static const char *const bond_arp_all_targets_table[_NETDEV_BOND_ARP_ALL_TARGETS_MAX] = {
110
        [NETDEV_BOND_ARP_ALL_TARGETS_ANY] = "any",
111
        [NETDEV_BOND_ARP_ALL_TARGETS_ALL] = "all",
112
};
113
114
DEFINE_STRING_TABLE_LOOKUP(bond_arp_all_targets, BondArpAllTargets);
115
DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_arp_all_targets, bond_arp_all_targets, BondArpAllTargets, "Failed to parse bond Arp all targets");
116
117
static const char *const bond_primary_reselect_table[_NETDEV_BOND_PRIMARY_RESELECT_MAX] = {
118
        [NETDEV_BOND_PRIMARY_RESELECT_ALWAYS] = "always",
119
        [NETDEV_BOND_PRIMARY_RESELECT_BETTER]= "better",
120
        [NETDEV_BOND_PRIMARY_RESELECT_FAILURE]= "failure",
121
};
122
123
DEFINE_STRING_TABLE_LOOKUP(bond_primary_reselect, BondPrimaryReselect);
124
DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_primary_reselect, bond_primary_reselect, BondPrimaryReselect, "Failed to parse bond primary reselect");
125
126
297
static int netdev_bond_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
127
297
        Bond *b;
128
297
        int r;
129
297
130
297
        assert(netdev);
131
297
        assert(!link);
132
297
        assert(m);
133
297
134
297
        b = BOND(netdev);
135
297
136
297
        assert(b);
137
297
138
297
        if (b->mode != _NETDEV_BOND_MODE_INVALID) {
139
7
                r = sd_netlink_message_append_u8(m, IFLA_BOND_MODE, b->mode);
140
7
                if (r < 0)
141
0
                        return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_MODE attribute: %m");
142
297
        }
143
297
144
297
        if (b->xmit_hash_policy != _NETDEV_BOND_XMIT_HASH_POLICY_INVALID) {
145
2
                r = sd_netlink_message_append_u8(m, IFLA_BOND_XMIT_HASH_POLICY, b->xmit_hash_policy);
146
2
                if (r < 0)
147
0
                        return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_XMIT_HASH_POLICY attribute: %m");
148
297
        }
149
297
150
297
        if (b->lacp_rate != _NETDEV_BOND_LACP_RATE_INVALID &&
151
297
            b->mode == NETDEV_BOND_MODE_802_3AD) {
152
2
                r = sd_netlink_message_append_u8(m, IFLA_BOND_AD_LACP_RATE, b->lacp_rate);
153
2
                if (r < 0)
154
0
                        return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_AD_LACP_RATE attribute: %m");
155
297
        }
156
297
157
297
        if (b->miimon != 0) {
158
46
                r = sd_netlink_message_append_u32(m, IFLA_BOND_MIIMON, b->miimon / USEC_PER_MSEC);
159
46
                if (r < 0)
160
46
                        log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_BOND_MIIMON attribute: %m");
161
46
        }
162
297
163
297
        if (b->downdelay != 0) {
164
42
                r = sd_netlink_message_append_u32(m, IFLA_BOND_DOWNDELAY, b->downdelay / USEC_PER_MSEC);
165
42
                if (r < 0)
166
0
                        return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_DOWNDELAY attribute: %m");
167
297
        }
168
297
169
297
        if (b->updelay != 0) {
170
74
                r = sd_netlink_message_append_u32(m, IFLA_BOND_UPDELAY, b->updelay / USEC_PER_MSEC);
171
74
                if (r < 0)
172
0
                        return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_UPDELAY attribute: %m");
173
297
        }
174
297
175
297
        if (b->arp_interval != 0) {
176
0
                r = sd_netlink_message_append_u32(m, IFLA_BOND_ARP_INTERVAL, b->arp_interval / USEC_PER_MSEC);
177
0
                if (r < 0)
178
0
                        return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_ARP_INTERVAL attribute: %m");
179
0
180
0
                if (b->lp_interval >= LEARNING_PACKETS_INTERVAL_MIN_SEC &&
181
0
                    b->lp_interval <= LEARNING_PACKETS_INTERVAL_MAX_SEC) {
182
0
                        r = sd_netlink_message_append_u32(m, IFLA_BOND_LP_INTERVAL, b->lp_interval / USEC_PER_SEC);
183
0
                        if (r < 0)
184
0
                                return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_LP_INTERVAL attribute: %m");
185
297
                }
186
0
        }
187
297
188
297
        if (b->ad_select != _NETDEV_BOND_AD_SELECT_INVALID &&
189
297
            b->mode == NETDEV_BOND_MODE_802_3AD) {
190
0
                r = sd_netlink_message_append_u8(m, IFLA_BOND_AD_SELECT, b->ad_select);
191
0
                if (r < 0)
192
0
                        return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_AD_SELECT attribute: %m");
193
297
        }
194
297
195
297
        if (b->fail_over_mac != _NETDEV_BOND_FAIL_OVER_MAC_INVALID &&
196
297
            b->mode == NETDEV_BOND_MODE_ACTIVE_BACKUP) {
197
0
                r = sd_netlink_message_append_u8(m, IFLA_BOND_FAIL_OVER_MAC, b->fail_over_mac);
198
0
                if (r < 0)
199
0
                        return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_FAIL_OVER_MAC attribute: %m");
200
297
        }
201
297
202
297
        if (b->arp_validate != _NETDEV_BOND_ARP_VALIDATE_INVALID) {
203
0
                r = sd_netlink_message_append_u32(m, IFLA_BOND_ARP_VALIDATE, b->arp_validate);
204
0
                if (r < 0)
205
0
                        return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_ARP_VALIDATE attribute: %m");
206
297
        }
207
297
208
297
        if (b->arp_all_targets != _NETDEV_BOND_ARP_ALL_TARGETS_INVALID) {
209
0
                r = sd_netlink_message_append_u32(m, IFLA_BOND_ARP_ALL_TARGETS, b->arp_all_targets);
210
0
                if (r < 0)
211
0
                        return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_ARP_ALL_TARGETS attribute: %m");
212
297
        }
213
297
214
297
        if (b->primary_reselect != _NETDEV_BOND_PRIMARY_RESELECT_INVALID) {
215
0
                r = sd_netlink_message_append_u8(m, IFLA_BOND_PRIMARY_RESELECT, b->primary_reselect);
216
0
                if (r < 0)
217
0
                        return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_PRIMARY_RESELECT attribute: %m");
218
297
        }
219
297
220
297
        if (b->resend_igmp <= RESEND_IGMP_MAX) {
221
274
                r = sd_netlink_message_append_u32(m, IFLA_BOND_RESEND_IGMP, b->resend_igmp);
222
274
                if (r < 0)
223
0
                        return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_RESEND_IGMP attribute: %m");
224
297
        }
225
297
226
297
        if (b->packets_per_slave <= PACKETS_PER_SLAVE_MAX &&
227
297
            b->mode == NETDEV_BOND_MODE_BALANCE_RR) {
228
0
                r = sd_netlink_message_append_u32(m, IFLA_BOND_PACKETS_PER_SLAVE, b->packets_per_slave);
229
0
                if (r < 0)
230
0
                        return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_PACKETS_PER_SLAVE attribute: %m");
231
297
        }
232
297
233
297
        if (b->num_grat_arp <= GRATUITOUS_ARP_MAX) {
234
297
                r = sd_netlink_message_append_u8(m, IFLA_BOND_NUM_PEER_NOTIF, b->num_grat_arp);
235
297
                if (r < 0)
236
0
                        return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_NUM_PEER_NOTIF attribute: %m");
237
297
        }
238
297
239
297
        if (b->min_links != 0) {
240
38
                r = sd_netlink_message_append_u32(m, IFLA_BOND_MIN_LINKS, b->min_links);
241
38
                if (r < 0)
242
0
                        return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_MIN_LINKS attribute: %m");
243
297
        }
244
297
245
297
        if (b->ad_actor_sys_prio != 0) {
246
16
                r = sd_netlink_message_append_u16(m, IFLA_BOND_AD_ACTOR_SYS_PRIO, b->ad_actor_sys_prio);
247
16
                if (r < 0)
248
0
                        return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_AD_ACTOR_SYS_PRIO attribute: %m");
249
297
        }
250
297
251
297
        if (b->ad_user_port_key != 0) {
252
9
                r = sd_netlink_message_append_u16(m, IFLA_BOND_AD_USER_PORT_KEY, b->ad_user_port_key);
253
9
                if (r < 0)
254
0
                        return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_AD_USER_PORT_KEY attribute: %m");
255
297
        }
256
297
257
297
        if (!ether_addr_is_null(&b->ad_actor_system)) {
258
4
                r = sd_netlink_message_append_ether_addr(m, IFLA_BOND_AD_ACTOR_SYSTEM, &b->ad_actor_system);
259
4
                if (r < 0)
260
0
                        return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_AD_ACTOR_SYSTEM attribute: %m");
261
297
        }
262
297
263
297
        r = sd_netlink_message_append_u8(m, IFLA_BOND_ALL_SLAVES_ACTIVE, b->all_slaves_active);
264
297
        if (r < 0)
265
0
                return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_ALL_SLAVES_ACTIVE attribute: %m");
266
297
267
297
        if (b->tlb_dynamic_lb >= 0) {
268
0
                r = sd_netlink_message_append_u8(m, IFLA_BOND_TLB_DYNAMIC_LB, b->tlb_dynamic_lb);
269
0
                if (r < 0)
270
0
                        return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_TLB_DYNAMIC_LB attribute: %m");
271
297
        }
272
297
273
297
        if (b->arp_interval > 0 && !ordered_set_isempty(b->arp_ip_targets)) {
274
0
                Iterator i;
275
0
                void *val;
276
0
                int n = 0;
277
0
278
0
                r = sd_netlink_message_open_container(m, IFLA_BOND_ARP_IP_TARGET);
279
0
                if (r < 0)
280
0
                        return log_netdev_error_errno(netdev, r, "Could not open contaniner IFLA_BOND_ARP_IP_TARGET : %m");
281
0
282
0
                ORDERED_SET_FOREACH(val, b->arp_ip_targets, i) {
283
0
                        r = sd_netlink_message_append_u32(m, n++, PTR_TO_UINT32(val));
284
0
                        if (r < 0)
285
0
                                return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_ARP_ALL_TARGETS attribute: %m");
286
0
                }
287
0
288
0
                r = sd_netlink_message_close_container(m);
289
0
                if (r < 0)
290
0
                        return log_netdev_error_errno(netdev, r, "Could not close contaniner IFLA_BOND_ARP_IP_TARGET : %m");
291
297
        }
292
297
293
297
        return 0;
294
297
}
295
296
0
static int link_set_bond_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
297
0
        int r;
298
0
299
0
        assert(m);
300
0
        assert(link);
301
0
        assert(link->ifname);
302
0
303
0
        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
304
0
                return 1;
305
0
306
0
        r = sd_netlink_message_get_errno(m);
307
0
        if (r < 0) {
308
0
                log_link_warning_errno(link, r, "Could not set bonding interface: %m");
309
0
                return 1;
310
0
        }
311
0
312
0
        return 1;
313
0
}
314
315
0
int link_set_bond(Link *link) {
316
0
        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
317
0
        int r;
318
0
319
0
        assert(link);
320
0
        assert(link->network);
321
0
322
0
        r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_NEWLINK, link->network->bond->ifindex);
323
0
        if (r < 0)
324
0
                return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
325
0
326
0
        r = sd_netlink_message_set_flags(req, NLM_F_REQUEST | NLM_F_ACK);
327
0
        if (r < 0)
328
0
                return log_link_error_errno(link, r, "Could not set netlink flags: %m");
329
0
330
0
        r = sd_netlink_message_open_container(req, IFLA_LINKINFO);
331
0
        if (r < 0)
332
0
                return log_link_error_errno(link, r, "Could not append IFLA_PROTINFO attribute: %m");
333
0
334
0
        r = sd_netlink_message_open_container_union(req, IFLA_INFO_DATA, "bond");
335
0
        if (r < 0)
336
0
                return log_link_error_errno(link, r, "Could not append IFLA_INFO_DATA attribute: %m");
337
0
338
0
        if (link->network->active_slave) {
339
0
                r = sd_netlink_message_append_u32(req, IFLA_BOND_ACTIVE_SLAVE, link->ifindex);
340
0
                if (r < 0)
341
0
                        return log_link_error_errno(link, r, "Could not append IFLA_BOND_ACTIVE_SLAVE attribute: %m");
342
0
        }
343
0
344
0
        if (link->network->primary_slave) {
345
0
                r = sd_netlink_message_append_u32(req, IFLA_BOND_PRIMARY, link->ifindex);
346
0
                if (r < 0)
347
0
                        return log_link_error_errno(link, r, "Could not append IFLA_BOND_PRIMARY attribute: %m");
348
0
        }
349
0
350
0
        r = sd_netlink_message_close_container(req);
351
0
        if (r < 0)
352
0
                return log_link_error_errno(link, r, "Could not append IFLA_LINKINFO attribute: %m");
353
0
354
0
        r = sd_netlink_message_close_container(req);
355
0
        if (r < 0)
356
0
                return log_link_error_errno(link, r, "Could not append IFLA_INFO_DATA attribute: %m");
357
0
358
0
        r = netlink_call_async(link->manager->rtnl, NULL, req, link_set_bond_handler,
359
0
                               link_netlink_destroy_callback, link);
360
0
        if (r < 0)
361
0
                return log_link_error_errno(link, r,  "Could not send rtnetlink message: %m");
362
0
363
0
        link_ref(link);
364
0
365
0
        return r;
366
0
}
367
368
int config_parse_arp_ip_target_address(
369
                const char *unit,
370
                const char *filename,
371
                unsigned line,
372
                const char *section,
373
                unsigned section_line,
374
                const char *lvalue,
375
                int ltype,
376
                const char *rvalue,
377
                void *data,
378
0
                void *userdata) {
379
0
380
0
        Bond *b = userdata;
381
0
        int r;
382
0
383
0
        assert(filename);
384
0
        assert(lvalue);
385
0
        assert(rvalue);
386
0
        assert(data);
387
0
388
0
        if (isempty(rvalue)) {
389
0
                b->arp_ip_targets = ordered_set_free(b->arp_ip_targets);
390
0
                return 0;
391
0
        }
392
0
393
0
        for (;;) {
394
0
                _cleanup_free_ char *n = NULL;
395
0
                union in_addr_union ip;
396
0
397
0
                r = extract_first_word(&rvalue, &n, NULL, 0);
398
0
                if (r < 0) {
399
0
                        log_syntax(unit, LOG_ERR, filename, line, r,
400
0
                                   "Failed to parse Bond ARP ip target address, ignoring assignment: %s",
401
0
                                   rvalue);
402
0
                        return 0;
403
0
                }
404
0
                if (r == 0)
405
0
                        return 0;
406
0
407
0
                r = in_addr_from_string(AF_INET, n, &ip);
408
0
                if (r < 0) {
409
0
                        log_syntax(unit, LOG_ERR, filename, line, r,
410
0
                                   "Bond ARP ip target address is invalid, ignoring assignment: %s", n);
411
0
                        continue;
412
0
                }
413
0
414
0
                r = ordered_set_ensure_allocated(&b->arp_ip_targets, NULL);
415
0
                if (r < 0)
416
0
                        return log_oom();
417
0
418
0
                if (ordered_set_size(b->arp_ip_targets) >= NETDEV_BOND_ARP_TARGETS_MAX) {
419
0
                        log_syntax(unit, LOG_WARNING, filename, line, 0,
420
0
                                   "Too many ARP ip targets are specified. The maximum number is %d. Ignoring assignment: %s",
421
0
                                   NETDEV_BOND_ARP_TARGETS_MAX, n);
422
0
                        continue;
423
0
                }
424
0
425
0
                r = ordered_set_put(b->arp_ip_targets, UINT32_TO_PTR(ip.in.s_addr));
426
0
                if (r == -EEXIST)
427
0
                        log_syntax(unit, LOG_WARNING, filename, line, r,
428
0
                                   "Bond ARP ip target address is duplicated, ignoring assignment: %s", n);
429
0
                if (r < 0)
430
0
                        log_syntax(unit, LOG_ERR, filename, line, r,
431
0
                                   "Failed to store bond ARP ip target address '%s', ignoring assignment: %m", n);
432
0
        }
433
0
}
434
435
int config_parse_ad_actor_sys_prio(
436
                const char *unit,
437
                const char *filename,
438
                unsigned line,
439
                const char *section,
440
                unsigned section_line,
441
                const char *lvalue,
442
                int ltype,
443
                const char *rvalue,
444
                void *data,
445
744
                void *userdata) {
446
744
        Bond *b = userdata;
447
744
        uint16_t v;
448
744
        int r;
449
744
450
744
        assert(filename);
451
744
        assert(lvalue);
452
744
        assert(rvalue);
453
744
        assert(data);
454
744
455
744
        r = safe_atou16(rvalue, &v);
456
744
        if (r < 0) {
457
201
                log_syntax(unit, LOG_ERR, filename, line, r,
458
201
                           "Failed to parse actor system priority '%s', ignoring: %m", rvalue);
459
201
                return 0;
460
201
        }
461
543
462
543
        if (v == 0) {
463
196
                log_syntax(unit, LOG_ERR, filename, line, 0,
464
196
                           "Failed to parse actor system priority '%s'. Range is [1,65535], ignoring.",
465
196
                           rvalue);
466
196
                return 0;
467
196
        }
468
347
469
347
        b->ad_actor_sys_prio = v;
470
347
471
347
        return 0;
472
347
}
473
474
int config_parse_ad_user_port_key(
475
                const char *unit,
476
                const char *filename,
477
                unsigned line,
478
                const char *section,
479
                unsigned section_line,
480
                const char *lvalue,
481
                int ltype,
482
                const char *rvalue,
483
                void *data,
484
709
                void *userdata) {
485
709
        Bond *b = userdata;
486
709
        uint16_t v;
487
709
        int r;
488
709
489
709
        assert(filename);
490
709
        assert(lvalue);
491
709
        assert(rvalue);
492
709
        assert(data);
493
709
494
709
        r = safe_atou16(rvalue, &v);
495
709
        if (r < 0) {
496
237
                log_syntax(unit, LOG_ERR, filename, line, r,
497
237
                           "Failed to parse user port key '%s', ignoring: %m", rvalue);
498
237
                return 0;
499
237
        }
500
472
501
472
        if (v > 1023) {
502
213
                log_syntax(unit, LOG_ERR, filename, line, 0,
503
213
                           "Failed to parse user port key '%s'. Range is [0…1023], ignoring.", rvalue);
504
213
                return 0;
505
213
        }
506
259
507
259
        b->ad_user_port_key = v;
508
259
509
259
        return 0;
510
259
}
511
512
int config_parse_ad_actor_system(
513
                const char *unit,
514
                const char *filename,
515
                unsigned line,
516
                const char *section,
517
                unsigned section_line,
518
                const char *lvalue,
519
                int ltype,
520
                const char *rvalue,
521
                void *data,
522
872
                void *userdata) {
523
872
        Bond *b = userdata;
524
872
        struct ether_addr n;
525
872
        int r;
526
872
527
872
        assert(filename);
528
872
        assert(lvalue);
529
872
        assert(rvalue);
530
872
        assert(data);
531
872
532
872
        r = ether_addr_from_string(rvalue, &n);
533
872
        if (r < 0) {
534
252
                log_syntax(unit, LOG_ERR, filename, line, r,
535
252
                           "Not a valid MAC address %s. Ignoring assignment: %m",
536
252
                           rvalue);
537
252
                return 0;
538
252
        }
539
620
        if (ether_addr_is_null(&n) || (n.ether_addr_octet[0] & 0x01)) {
540
391
                log_syntax(unit, LOG_ERR, filename, line, 0,
541
391
                           "Not a valid MAC address %s, can not be null or multicast. Ignoring assignment.",
542
391
                           rvalue);
543
391
                return 0;
544
391
        }
545
229
546
229
        b->ad_actor_system = n;
547
229
548
229
        return 0;
549
229
}
550
551
1.15k
static void bond_done(NetDev *netdev) {
552
1.15k
        Bond *b;
553
1.15k
554
1.15k
        assert(netdev);
555
1.15k
        b = BOND(netdev);
556
1.15k
        assert(b);
557
1.15k
558
1.15k
        ordered_set_free(b->arp_ip_targets);
559
1.15k
}
560
561
1.15k
static void bond_init(NetDev *netdev) {
562
1.15k
        Bond *b;
563
1.15k
564
1.15k
        assert(netdev);
565
1.15k
566
1.15k
        b = BOND(netdev);
567
1.15k
568
1.15k
        assert(b);
569
1.15k
570
1.15k
        b->mode = _NETDEV_BOND_MODE_INVALID;
571
1.15k
        b->xmit_hash_policy = _NETDEV_BOND_XMIT_HASH_POLICY_INVALID;
572
1.15k
        b->lacp_rate = _NETDEV_BOND_LACP_RATE_INVALID;
573
1.15k
        b->ad_select = _NETDEV_BOND_AD_SELECT_INVALID;
574
1.15k
        b->fail_over_mac = _NETDEV_BOND_FAIL_OVER_MAC_INVALID;
575
1.15k
        b->arp_validate = _NETDEV_BOND_ARP_VALIDATE_INVALID;
576
1.15k
        b->arp_all_targets = _NETDEV_BOND_ARP_ALL_TARGETS_INVALID;
577
1.15k
        b->primary_reselect = _NETDEV_BOND_PRIMARY_RESELECT_INVALID;
578
1.15k
579
1.15k
        b->all_slaves_active = false;
580
1.15k
        b->tlb_dynamic_lb = -1;
581
1.15k
582
1.15k
        b->resend_igmp = RESEND_IGMP_DEFAULT;
583
1.15k
        b->packets_per_slave = PACKETS_PER_SLAVE_DEFAULT;
584
1.15k
        b->num_grat_arp = GRATUITOUS_ARP_DEFAULT;
585
1.15k
        b->lp_interval = LEARNING_PACKETS_INTERVAL_MIN_SEC;
586
1.15k
}
587
588
const NetDevVTable bond_vtable = {
589
        .object_size = sizeof(Bond),
590
        .init = bond_init,
591
        .done = bond_done,
592
        .sections = "Match\0NetDev\0Bond\0",
593
        .fill_message_create = netdev_bond_fill_message_create,
594
        .create_type = NETDEV_CREATE_MASTER,
595
        .generate_mac = true,
596
};