Line data Source code
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 : #define LEARNING_PACKETS_INTERVAL_MIN_SEC (1 * USEC_PER_SEC)
20 : #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 : #define RESEND_IGMP_MAX 255
27 : #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 : #define PACKETS_PER_SLAVE_MAX 65535
35 : #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 : #define GRATUITOUS_ARP_MAX 255
44 : #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 18 : DEFINE_STRING_TABLE_LOOKUP(bond_mode, BondMode);
57 0 : 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 14 : DEFINE_STRING_TABLE_LOOKUP(bond_xmit_hash_policy, BondXmitHashPolicy);
68 0 : 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 8 : DEFINE_STRING_TABLE_LOOKUP(bond_lacp_rate, BondLacpRate);
79 0 : 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 10 : DEFINE_STRING_TABLE_LOOKUP(bond_ad_select, BondAdSelect);
88 0 : 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 10 : DEFINE_STRING_TABLE_LOOKUP(bond_fail_over_mac, BondFailOverMac);
97 0 : 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 12 : DEFINE_STRING_TABLE_LOOKUP(bond_arp_validate, BondArpValidate);
107 0 : 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 8 : DEFINE_STRING_TABLE_LOOKUP(bond_arp_all_targets, BondArpAllTargets);
115 0 : 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 10 : DEFINE_STRING_TABLE_LOOKUP(bond_primary_reselect, BondPrimaryReselect);
124 0 : DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_primary_reselect, bond_primary_reselect, BondPrimaryReselect, "Failed to parse bond primary reselect");
125 :
126 0 : static int netdev_bond_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
127 : Bond *b;
128 : int r;
129 :
130 0 : assert(netdev);
131 0 : assert(!link);
132 0 : assert(m);
133 :
134 0 : b = BOND(netdev);
135 :
136 0 : assert(b);
137 :
138 0 : if (b->mode != _NETDEV_BOND_MODE_INVALID) {
139 0 : r = sd_netlink_message_append_u8(m, IFLA_BOND_MODE, b->mode);
140 0 : if (r < 0)
141 0 : return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_MODE attribute: %m");
142 : }
143 :
144 0 : if (b->xmit_hash_policy != _NETDEV_BOND_XMIT_HASH_POLICY_INVALID) {
145 0 : r = sd_netlink_message_append_u8(m, IFLA_BOND_XMIT_HASH_POLICY, b->xmit_hash_policy);
146 0 : if (r < 0)
147 0 : return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_XMIT_HASH_POLICY attribute: %m");
148 : }
149 :
150 0 : if (b->lacp_rate != _NETDEV_BOND_LACP_RATE_INVALID &&
151 0 : b->mode == NETDEV_BOND_MODE_802_3AD) {
152 0 : r = sd_netlink_message_append_u8(m, IFLA_BOND_AD_LACP_RATE, b->lacp_rate);
153 0 : if (r < 0)
154 0 : return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_AD_LACP_RATE attribute: %m");
155 : }
156 :
157 0 : if (b->miimon != 0) {
158 0 : r = sd_netlink_message_append_u32(m, IFLA_BOND_MIIMON, b->miimon / USEC_PER_MSEC);
159 0 : if (r < 0)
160 0 : log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_BOND_MIIMON attribute: %m");
161 : }
162 :
163 0 : if (b->downdelay != 0) {
164 0 : r = sd_netlink_message_append_u32(m, IFLA_BOND_DOWNDELAY, b->downdelay / USEC_PER_MSEC);
165 0 : if (r < 0)
166 0 : return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_DOWNDELAY attribute: %m");
167 : }
168 :
169 0 : if (b->updelay != 0) {
170 0 : r = sd_netlink_message_append_u32(m, IFLA_BOND_UPDELAY, b->updelay / USEC_PER_MSEC);
171 0 : if (r < 0)
172 0 : return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_UPDELAY attribute: %m");
173 : }
174 :
175 0 : 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 :
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 : }
186 : }
187 :
188 0 : if (b->ad_select != _NETDEV_BOND_AD_SELECT_INVALID &&
189 0 : 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 : }
194 :
195 0 : if (b->fail_over_mac != _NETDEV_BOND_FAIL_OVER_MAC_INVALID &&
196 0 : 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 : }
201 :
202 0 : 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 : }
207 :
208 0 : 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 : }
213 :
214 0 : 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 : }
219 :
220 0 : if (b->resend_igmp <= RESEND_IGMP_MAX) {
221 0 : r = sd_netlink_message_append_u32(m, IFLA_BOND_RESEND_IGMP, b->resend_igmp);
222 0 : if (r < 0)
223 0 : return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_RESEND_IGMP attribute: %m");
224 : }
225 :
226 0 : if (b->packets_per_slave <= PACKETS_PER_SLAVE_MAX &&
227 0 : 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 : }
232 :
233 0 : if (b->num_grat_arp <= GRATUITOUS_ARP_MAX) {
234 0 : r = sd_netlink_message_append_u8(m, IFLA_BOND_NUM_PEER_NOTIF, b->num_grat_arp);
235 0 : if (r < 0)
236 0 : return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_NUM_PEER_NOTIF attribute: %m");
237 : }
238 :
239 0 : if (b->min_links != 0) {
240 0 : r = sd_netlink_message_append_u32(m, IFLA_BOND_MIN_LINKS, b->min_links);
241 0 : if (r < 0)
242 0 : return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_MIN_LINKS attribute: %m");
243 : }
244 :
245 0 : if (b->ad_actor_sys_prio != 0) {
246 0 : r = sd_netlink_message_append_u16(m, IFLA_BOND_AD_ACTOR_SYS_PRIO, b->ad_actor_sys_prio);
247 0 : if (r < 0)
248 0 : return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_AD_ACTOR_SYS_PRIO attribute: %m");
249 : }
250 :
251 0 : if (b->ad_user_port_key != 0) {
252 0 : r = sd_netlink_message_append_u16(m, IFLA_BOND_AD_USER_PORT_KEY, b->ad_user_port_key);
253 0 : if (r < 0)
254 0 : return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_AD_USER_PORT_KEY attribute: %m");
255 : }
256 :
257 0 : if (!ether_addr_is_null(&b->ad_actor_system)) {
258 0 : r = sd_netlink_message_append_ether_addr(m, IFLA_BOND_AD_ACTOR_SYSTEM, &b->ad_actor_system);
259 0 : if (r < 0)
260 0 : return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_AD_ACTOR_SYSTEM attribute: %m");
261 : }
262 :
263 0 : r = sd_netlink_message_append_u8(m, IFLA_BOND_ALL_SLAVES_ACTIVE, b->all_slaves_active);
264 0 : if (r < 0)
265 0 : return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_ALL_SLAVES_ACTIVE attribute: %m");
266 :
267 0 : 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 : }
272 :
273 0 : if (b->arp_interval > 0 && !ordered_set_isempty(b->arp_ip_targets)) {
274 : Iterator i;
275 : void *val;
276 0 : int n = 0;
277 :
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 :
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 : }
287 :
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 : }
292 :
293 0 : return 0;
294 : }
295 :
296 0 : static int link_set_bond_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
297 : int r;
298 :
299 0 : assert(m);
300 0 : assert(link);
301 0 : assert(link->ifname);
302 :
303 0 : if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
304 0 : return 1;
305 :
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 : }
311 :
312 0 : return 1;
313 : }
314 :
315 0 : int link_set_bond(Link *link) {
316 0 : _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
317 : int r;
318 :
319 0 : assert(link);
320 0 : assert(link->network);
321 :
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 :
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 :
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 :
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 :
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 : }
343 :
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 : }
349 :
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 :
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 :
358 0 : r = netlink_call_async(link->manager->rtnl, NULL, req, link_set_bond_handler,
359 : 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 :
363 0 : link_ref(link);
364 :
365 0 : return r;
366 : }
367 :
368 0 : 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 : void *userdata) {
379 :
380 0 : Bond *b = userdata;
381 : int r;
382 :
383 0 : assert(filename);
384 0 : assert(lvalue);
385 0 : assert(rvalue);
386 0 : assert(data);
387 :
388 0 : if (isempty(rvalue)) {
389 0 : b->arp_ip_targets = ordered_set_free(b->arp_ip_targets);
390 0 : return 0;
391 : }
392 :
393 0 : for (;;) {
394 0 : _cleanup_free_ char *n = NULL;
395 : union in_addr_union ip;
396 :
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 : "Failed to parse Bond ARP ip target address, ignoring assignment: %s",
401 : rvalue);
402 0 : return 0;
403 : }
404 0 : if (r == 0)
405 0 : return 0;
406 :
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 : "Bond ARP ip target address is invalid, ignoring assignment: %s", n);
411 0 : continue;
412 : }
413 :
414 0 : r = ordered_set_ensure_allocated(&b->arp_ip_targets, NULL);
415 0 : if (r < 0)
416 0 : return log_oom();
417 :
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 : "Too many ARP ip targets are specified. The maximum number is %d. Ignoring assignment: %s",
421 : NETDEV_BOND_ARP_TARGETS_MAX, n);
422 0 : continue;
423 : }
424 :
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 : "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 : "Failed to store bond ARP ip target address '%s', ignoring assignment: %m", n);
432 : }
433 : }
434 :
435 0 : 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 : void *userdata) {
446 0 : Bond *b = userdata;
447 : uint16_t v;
448 : int r;
449 :
450 0 : assert(filename);
451 0 : assert(lvalue);
452 0 : assert(rvalue);
453 0 : assert(data);
454 :
455 0 : r = safe_atou16(rvalue, &v);
456 0 : if (r < 0) {
457 0 : log_syntax(unit, LOG_ERR, filename, line, r,
458 : "Failed to parse actor system priority '%s', ignoring: %m", rvalue);
459 0 : return 0;
460 : }
461 :
462 0 : if (v == 0) {
463 0 : log_syntax(unit, LOG_ERR, filename, line, 0,
464 : "Failed to parse actor system priority '%s'. Range is [1,65535], ignoring.",
465 : rvalue);
466 0 : return 0;
467 : }
468 :
469 0 : b->ad_actor_sys_prio = v;
470 :
471 0 : return 0;
472 : }
473 :
474 0 : 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 : void *userdata) {
485 0 : Bond *b = userdata;
486 : uint16_t v;
487 : int r;
488 :
489 0 : assert(filename);
490 0 : assert(lvalue);
491 0 : assert(rvalue);
492 0 : assert(data);
493 :
494 0 : r = safe_atou16(rvalue, &v);
495 0 : if (r < 0) {
496 0 : log_syntax(unit, LOG_ERR, filename, line, r,
497 : "Failed to parse user port key '%s', ignoring: %m", rvalue);
498 0 : return 0;
499 : }
500 :
501 0 : if (v > 1023) {
502 0 : log_syntax(unit, LOG_ERR, filename, line, 0,
503 : "Failed to parse user port key '%s'. Range is [0…1023], ignoring.", rvalue);
504 0 : return 0;
505 : }
506 :
507 0 : b->ad_user_port_key = v;
508 :
509 0 : return 0;
510 : }
511 :
512 0 : 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 : void *userdata) {
523 0 : Bond *b = userdata;
524 : struct ether_addr n;
525 : int r;
526 :
527 0 : assert(filename);
528 0 : assert(lvalue);
529 0 : assert(rvalue);
530 0 : assert(data);
531 :
532 0 : r = ether_addr_from_string(rvalue, &n);
533 0 : if (r < 0) {
534 0 : log_syntax(unit, LOG_ERR, filename, line, r,
535 : "Not a valid MAC address %s. Ignoring assignment: %m",
536 : rvalue);
537 0 : return 0;
538 : }
539 0 : if (ether_addr_is_null(&n) || (n.ether_addr_octet[0] & 0x01)) {
540 0 : log_syntax(unit, LOG_ERR, filename, line, 0,
541 : "Not a valid MAC address %s, can not be null or multicast. Ignoring assignment.",
542 : rvalue);
543 0 : return 0;
544 : }
545 :
546 0 : b->ad_actor_system = n;
547 :
548 0 : return 0;
549 : }
550 :
551 0 : static void bond_done(NetDev *netdev) {
552 : Bond *b;
553 :
554 0 : assert(netdev);
555 0 : b = BOND(netdev);
556 0 : assert(b);
557 :
558 0 : ordered_set_free(b->arp_ip_targets);
559 0 : }
560 :
561 0 : static void bond_init(NetDev *netdev) {
562 : Bond *b;
563 :
564 0 : assert(netdev);
565 :
566 0 : b = BOND(netdev);
567 :
568 0 : assert(b);
569 :
570 0 : b->mode = _NETDEV_BOND_MODE_INVALID;
571 0 : b->xmit_hash_policy = _NETDEV_BOND_XMIT_HASH_POLICY_INVALID;
572 0 : b->lacp_rate = _NETDEV_BOND_LACP_RATE_INVALID;
573 0 : b->ad_select = _NETDEV_BOND_AD_SELECT_INVALID;
574 0 : b->fail_over_mac = _NETDEV_BOND_FAIL_OVER_MAC_INVALID;
575 0 : b->arp_validate = _NETDEV_BOND_ARP_VALIDATE_INVALID;
576 0 : b->arp_all_targets = _NETDEV_BOND_ARP_ALL_TARGETS_INVALID;
577 0 : b->primary_reselect = _NETDEV_BOND_PRIMARY_RESELECT_INVALID;
578 :
579 0 : b->all_slaves_active = false;
580 0 : b->tlb_dynamic_lb = -1;
581 :
582 0 : b->resend_igmp = RESEND_IGMP_DEFAULT;
583 0 : b->packets_per_slave = PACKETS_PER_SLAVE_DEFAULT;
584 0 : b->num_grat_arp = GRATUITOUS_ARP_DEFAULT;
585 0 : b->lp_interval = LEARNING_PACKETS_INTERVAL_MIN_SEC;
586 0 : }
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 : };
|