]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/network/networkd-address.c
core: move reset_arguments() to the end of main's finish
[thirdparty/systemd.git] / src / network / networkd-address.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #include <net/if.h>
4
5 #include "alloc-util.h"
6 #include "conf-parser.h"
7 #include "firewall-util.h"
8 #include "memory-util.h"
9 #include "missing_network.h"
10 #include "netlink-util.h"
11 #include "networkd-address.h"
12 #include "networkd-manager.h"
13 #include "networkd-ndisc.h"
14 #include "parse-util.h"
15 #include "set.h"
16 #include "socket-util.h"
17 #include "string-util.h"
18 #include "strv.h"
19 #include "utf8.h"
20
21 #define ADDRESSES_PER_LINK_MAX 2048U
22 #define STATIC_ADDRESSES_PER_NETWORK_MAX 1024U
23
24 int generate_ipv6_eui_64_address(Link *link, struct in6_addr *ret) {
25 assert(link);
26 assert(ret);
27
28 /* see RFC4291 section 2.5.1 */
29 ret->s6_addr[8] = link->mac.ether_addr_octet[0];
30 ret->s6_addr[8] ^= 1 << 1;
31 ret->s6_addr[9] = link->mac.ether_addr_octet[1];
32 ret->s6_addr[10] = link->mac.ether_addr_octet[2];
33 ret->s6_addr[11] = 0xff;
34 ret->s6_addr[12] = 0xfe;
35 ret->s6_addr[13] = link->mac.ether_addr_octet[3];
36 ret->s6_addr[14] = link->mac.ether_addr_octet[4];
37 ret->s6_addr[15] = link->mac.ether_addr_octet[5];
38
39 return 0;
40 }
41
42 int address_new(Address **ret) {
43 _cleanup_(address_freep) Address *address = NULL;
44
45 address = new(Address, 1);
46 if (!address)
47 return -ENOMEM;
48
49 *address = (Address) {
50 .family = AF_UNSPEC,
51 .scope = RT_SCOPE_UNIVERSE,
52 .cinfo.ifa_prefered = CACHE_INFO_INFINITY_LIFE_TIME,
53 .cinfo.ifa_valid = CACHE_INFO_INFINITY_LIFE_TIME,
54 .duplicate_address_detection = ADDRESS_FAMILY_IPV6,
55 .prefix_route = true,
56 };
57
58 *ret = TAKE_PTR(address);
59
60 return 0;
61 }
62
63 static int address_new_static(Network *network, const char *filename, unsigned section_line, Address **ret) {
64 _cleanup_(network_config_section_freep) NetworkConfigSection *n = NULL;
65 _cleanup_(address_freep) Address *address = NULL;
66 int r;
67
68 assert(network);
69 assert(ret);
70 assert(!!filename == (section_line > 0));
71
72 if (filename) {
73 r = network_config_section_new(filename, section_line, &n);
74 if (r < 0)
75 return r;
76
77 address = hashmap_get(network->addresses_by_section, n);
78 if (address) {
79 *ret = TAKE_PTR(address);
80
81 return 0;
82 }
83 }
84
85 if (network->n_static_addresses >= STATIC_ADDRESSES_PER_NETWORK_MAX)
86 return -E2BIG;
87
88 r = address_new(&address);
89 if (r < 0)
90 return r;
91
92 address->network = network;
93 LIST_APPEND(addresses, network->static_addresses, address);
94 network->n_static_addresses++;
95
96 if (filename) {
97 address->section = TAKE_PTR(n);
98
99 r = hashmap_ensure_allocated(&network->addresses_by_section, &network_config_hash_ops);
100 if (r < 0)
101 return r;
102
103 r = hashmap_put(network->addresses_by_section, address->section, address);
104 if (r < 0)
105 return r;
106 }
107
108 *ret = TAKE_PTR(address);
109
110 return 0;
111 }
112
113 void address_free(Address *address) {
114 if (!address)
115 return;
116
117 if (address->network) {
118 LIST_REMOVE(addresses, address->network->static_addresses, address);
119 assert(address->network->n_static_addresses > 0);
120 address->network->n_static_addresses--;
121
122 if (address->section)
123 hashmap_remove(address->network->addresses_by_section, address->section);
124 }
125
126 if (address->link && !address->acd) {
127 NDiscAddress *n;
128
129 set_remove(address->link->addresses, address);
130 set_remove(address->link->addresses_foreign, address);
131 set_remove(address->link->static_addresses, address);
132 if (address->link->dhcp_address == address)
133 address->link->dhcp_address = NULL;
134 if (address->link->dhcp_address_old == address)
135 address->link->dhcp_address_old = NULL;
136 set_remove(address->link->dhcp6_addresses, address);
137 set_remove(address->link->dhcp6_addresses_old, address);
138 set_remove(address->link->dhcp6_pd_addresses, address);
139 set_remove(address->link->dhcp6_pd_addresses_old, address);
140 SET_FOREACH(n, address->link->ndisc_addresses)
141 if (n->address == address)
142 free(set_remove(address->link->ndisc_addresses, n));
143
144 if (in_addr_equal(AF_INET6, &address->in_addr, (const union in_addr_union *) &address->link->ipv6ll_address))
145 memzero(&address->link->ipv6ll_address, sizeof(struct in6_addr));
146 }
147
148 sd_ipv4acd_unref(address->acd);
149
150 network_config_section_free(address->section);
151 free(address->label);
152 free(address);
153 }
154
155 static uint32_t address_prefix(const Address *a) {
156 assert(a);
157
158 /* make sure we don't try to shift by 32.
159 * See ISO/IEC 9899:TC3 ยง 6.5.7.3. */
160 if (a->prefixlen == 0)
161 return 0;
162
163 if (a->in_addr_peer.in.s_addr != 0)
164 return be32toh(a->in_addr_peer.in.s_addr) >> (32 - a->prefixlen);
165 else
166 return be32toh(a->in_addr.in.s_addr) >> (32 - a->prefixlen);
167 }
168
169 void address_hash_func(const Address *a, struct siphash *state) {
170 assert(a);
171
172 siphash24_compress(&a->family, sizeof(a->family), state);
173
174 switch (a->family) {
175 case AF_INET:
176 siphash24_compress(&a->prefixlen, sizeof(a->prefixlen), state);
177
178 /* peer prefix */
179 uint32_t prefix = address_prefix(a);
180 siphash24_compress(&prefix, sizeof(prefix), state);
181
182 _fallthrough_;
183 case AF_INET6:
184 /* local address */
185 siphash24_compress(&a->in_addr, FAMILY_ADDRESS_SIZE(a->family), state);
186
187 break;
188 default:
189 /* treat any other address family as AF_UNSPEC */
190 break;
191 }
192 }
193
194 int address_compare_func(const Address *a1, const Address *a2) {
195 int r;
196
197 r = CMP(a1->family, a2->family);
198 if (r != 0)
199 return r;
200
201 switch (a1->family) {
202 /* use the same notion of equality as the kernel does */
203 case AF_INET:
204 r = CMP(a1->prefixlen, a2->prefixlen);
205 if (r != 0)
206 return r;
207
208 uint32_t prefix1 = address_prefix(a1);
209 uint32_t prefix2 = address_prefix(a2);
210 r = CMP(prefix1, prefix2);
211 if (r != 0)
212 return r;
213
214 _fallthrough_;
215 case AF_INET6:
216 return memcmp(&a1->in_addr, &a2->in_addr, FAMILY_ADDRESS_SIZE(a1->family));
217 default:
218 /* treat any other address family as AF_UNSPEC */
219 return 0;
220 }
221 }
222
223 DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(address_hash_ops, Address, address_hash_func, address_compare_func, address_free);
224
225 bool address_equal(Address *a1, Address *a2) {
226 if (a1 == a2)
227 return true;
228
229 if (!a1 || !a2)
230 return false;
231
232 return address_compare_func(a1, a2) == 0;
233 }
234
235 static int address_establish(Address *address, Link *link) {
236 bool masq;
237 int r;
238
239 assert(address);
240 assert(link);
241
242 masq = link->network &&
243 link->network->ip_masquerade &&
244 address->family == AF_INET &&
245 address->scope < RT_SCOPE_LINK;
246
247 /* Add firewall entry if this is requested */
248 if (address->ip_masquerade_done != masq) {
249 union in_addr_union masked = address->in_addr;
250 in_addr_mask(address->family, &masked, address->prefixlen);
251
252 r = fw_add_masquerade(masq, AF_INET, 0, &masked, address->prefixlen, NULL, NULL, 0);
253 if (r < 0)
254 return r;
255
256 address->ip_masquerade_done = masq;
257 }
258
259 return 0;
260 }
261
262 static int address_add_internal(Link *link, Set **addresses,
263 int family,
264 const union in_addr_union *in_addr,
265 unsigned char prefixlen,
266 Address **ret) {
267 _cleanup_(address_freep) Address *address = NULL;
268 int r;
269
270 assert(link);
271 assert(addresses);
272 assert(in_addr);
273
274 r = address_new(&address);
275 if (r < 0)
276 return r;
277
278 address->family = family;
279 address->in_addr = *in_addr;
280 address->prefixlen = prefixlen;
281 /* Consider address tentative until we get the real flags from the kernel */
282 address->flags = IFA_F_TENTATIVE;
283
284 r = set_ensure_put(addresses, &address_hash_ops, address);
285 if (r < 0)
286 return r;
287 if (r == 0)
288 return -EEXIST;
289
290 address->link = link;
291
292 if (ret)
293 *ret = address;
294 TAKE_PTR(address);
295 return 0;
296 }
297
298 int address_add_foreign(Link *link, int family, const union in_addr_union *in_addr, unsigned char prefixlen, Address **ret) {
299 return address_add_internal(link, &link->addresses_foreign, family, in_addr, prefixlen, ret);
300 }
301
302 int address_add(Link *link, int family, const union in_addr_union *in_addr, unsigned char prefixlen, Address **ret) {
303 Address *address;
304 int r;
305
306 r = address_get(link, family, in_addr, prefixlen, &address);
307 if (r == -ENOENT) {
308 /* Address does not exist, create a new one */
309 r = address_add_internal(link, &link->addresses, family, in_addr, prefixlen, &address);
310 if (r < 0)
311 return r;
312 } else if (r == 0) {
313 /* Take over a foreign address */
314 r = set_ensure_put(&link->addresses, &address_hash_ops, address);
315 if (r < 0)
316 return r;
317
318 set_remove(link->addresses_foreign, address);
319 } else if (r == 1) {
320 /* Already exists, do nothing */
321 ;
322 } else
323 return r;
324
325 if (ret)
326 *ret = address;
327
328 return 0;
329 }
330
331 static int address_release(Address *address) {
332 int r;
333
334 assert(address);
335 assert(address->link);
336
337 /* Remove masquerading firewall entry if it was added */
338 if (address->ip_masquerade_done) {
339 union in_addr_union masked = address->in_addr;
340 in_addr_mask(address->family, &masked, address->prefixlen);
341
342 r = fw_add_masquerade(false, AF_INET, 0, &masked, address->prefixlen, NULL, NULL, 0);
343 if (r < 0)
344 return r;
345
346 address->ip_masquerade_done = false;
347 }
348
349 return 0;
350 }
351
352 int address_update(
353 Address *address,
354 unsigned char flags,
355 unsigned char scope,
356 const struct ifa_cacheinfo *cinfo) {
357
358 bool ready;
359 int r;
360
361 assert(address);
362 assert(address->link);
363 assert(cinfo);
364
365 ready = address_is_ready(address);
366
367 address->flags = flags;
368 address->scope = scope;
369 address->cinfo = *cinfo;
370
371 if (IN_SET(address->link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
372 return 0;
373
374 link_update_operstate(address->link, true);
375 link_check_ready(address->link);
376
377 if (!ready && address_is_ready(address)) {
378 if (address->callback) {
379 r = address->callback(address);
380 if (r < 0)
381 return r;
382 }
383
384 if (address->family == AF_INET6 &&
385 in_addr_is_link_local(AF_INET6, &address->in_addr) > 0 &&
386 IN6_IS_ADDR_UNSPECIFIED(&address->link->ipv6ll_address) > 0) {
387
388 r = link_ipv6ll_gained(address->link, &address->in_addr.in6);
389 if (r < 0)
390 return r;
391 }
392 }
393
394 return 0;
395 }
396
397 int address_drop(Address *address) {
398 Link *link;
399 bool ready;
400 int r;
401
402 assert(address);
403
404 ready = address_is_ready(address);
405 link = address->link;
406
407 r = address_release(address);
408 if (r < 0)
409 log_link_warning_errno(link, r, "Failed to disable IP masquerading, ignoring: %m");
410
411 address_free(address);
412
413 link_update_operstate(link, true);
414
415 if (link && !ready)
416 link_check_ready(link);
417
418 return 0;
419 }
420
421 int address_get(Link *link,
422 int family,
423 const union in_addr_union *in_addr,
424 unsigned char prefixlen,
425 Address **ret) {
426
427 Address address, *existing;
428
429 assert(link);
430 assert(in_addr);
431
432 address = (Address) {
433 .family = family,
434 .in_addr = *in_addr,
435 .prefixlen = prefixlen,
436 };
437
438 existing = set_get(link->addresses, &address);
439 if (existing) {
440 if (ret)
441 *ret = existing;
442 return 1;
443 }
444
445 existing = set_get(link->addresses_foreign, &address);
446 if (existing) {
447 if (ret)
448 *ret = existing;
449 return 0;
450 }
451
452 return -ENOENT;
453 }
454
455 static bool address_exists_internal(Set *addresses, int family, const union in_addr_union *in_addr) {
456 Address *address;
457
458 SET_FOREACH(address, addresses) {
459 if (address->family != family)
460 continue;
461 if (in_addr_equal(address->family, &address->in_addr, in_addr))
462 return true;
463 }
464
465 return false;
466 }
467
468 bool address_exists(Link *link, int family, const union in_addr_union *in_addr) {
469 assert(link);
470 assert(IN_SET(family, AF_INET, AF_INET6));
471 assert(in_addr);
472
473 if (address_exists_internal(link->addresses, family, in_addr))
474 return true;
475 if (address_exists_internal(link->addresses_foreign, family, in_addr))
476 return true;
477 return false;
478 }
479
480 static int address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
481 int r;
482
483 assert(m);
484 assert(link);
485 assert(link->ifname);
486
487 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
488 return 1;
489
490 r = sd_netlink_message_get_errno(m);
491 if (r < 0 && r != -EADDRNOTAVAIL)
492 log_link_message_warning_errno(link, m, r, "Could not drop address");
493 else if (r >= 0)
494 (void) manager_rtnl_process_address(rtnl, m, link->manager);
495
496 return 1;
497 }
498
499 int address_remove(
500 Address *address,
501 Link *link,
502 link_netlink_message_handler_t callback) {
503
504 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
505 int r;
506
507 assert(address);
508 assert(IN_SET(address->family, AF_INET, AF_INET6));
509 assert(link);
510 assert(link->ifindex > 0);
511 assert(link->manager);
512 assert(link->manager->rtnl);
513
514 if (DEBUG_LOGGING) {
515 _cleanup_free_ char *b = NULL;
516
517 (void) in_addr_to_string(address->family, &address->in_addr, &b);
518 log_link_debug(link, "Removing address %s", strna(b));
519 }
520
521 r = sd_rtnl_message_new_addr(link->manager->rtnl, &req, RTM_DELADDR,
522 link->ifindex, address->family);
523 if (r < 0)
524 return log_link_error_errno(link, r, "Could not allocate RTM_DELADDR message: %m");
525
526 r = sd_rtnl_message_addr_set_prefixlen(req, address->prefixlen);
527 if (r < 0)
528 return log_link_error_errno(link, r, "Could not set prefixlen: %m");
529
530 r = netlink_message_append_in_addr_union(req, IFA_LOCAL, address->family, &address->in_addr);
531 if (r < 0)
532 return log_link_error_errno(link, r, "Could not append IFA_LOCAL attribute: %m");
533
534 r = netlink_call_async(link->manager->rtnl, NULL, req,
535 callback ?: address_remove_handler,
536 link_netlink_destroy_callback, link);
537 if (r < 0)
538 return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
539
540 link_ref(link);
541
542 return 0;
543 }
544
545 static int address_acquire(Link *link, Address *original, Address **ret) {
546 union in_addr_union in_addr = IN_ADDR_NULL;
547 struct in_addr broadcast = {};
548 _cleanup_(address_freep) Address *na = NULL;
549 int r;
550
551 assert(link);
552 assert(original);
553 assert(ret);
554
555 /* Something useful was configured? just use it */
556 r = in_addr_is_null(original->family, &original->in_addr);
557 if (r <= 0)
558 return r;
559
560 /* The address is configured to be 0.0.0.0 or [::] by the user?
561 * Then let's acquire something more useful from the pool. */
562 r = manager_address_pool_acquire(link->manager, original->family, original->prefixlen, &in_addr);
563 if (r < 0)
564 return r;
565 if (r == 0)
566 return -EBUSY;
567
568 if (original->family == AF_INET) {
569 /* Pick first address in range for ourselves ... */
570 in_addr.in.s_addr = in_addr.in.s_addr | htobe32(1);
571
572 /* .. and use last as broadcast address */
573 if (original->prefixlen > 30)
574 broadcast.s_addr = 0;
575 else
576 broadcast.s_addr = in_addr.in.s_addr | htobe32(0xFFFFFFFFUL >> original->prefixlen);
577 } else if (original->family == AF_INET6)
578 in_addr.in6.s6_addr[15] |= 1;
579
580 r = address_new(&na);
581 if (r < 0)
582 return r;
583
584 na->family = original->family;
585 na->prefixlen = original->prefixlen;
586 na->scope = original->scope;
587 na->cinfo = original->cinfo;
588
589 if (original->label) {
590 na->label = strdup(original->label);
591 if (!na->label)
592 return -ENOMEM;
593 }
594
595 na->broadcast = broadcast;
596 na->in_addr = in_addr;
597
598 LIST_PREPEND(addresses, link->pool_addresses, na);
599
600 *ret = TAKE_PTR(na);
601
602 return 0;
603 }
604
605 int address_configure(
606 Address *address,
607 Link *link,
608 link_netlink_message_handler_t callback,
609 bool update,
610 Address **ret) {
611
612 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
613 Address *a;
614 int r;
615
616 assert(address);
617 assert(IN_SET(address->family, AF_INET, AF_INET6));
618 assert(link);
619 assert(link->ifindex > 0);
620 assert(link->manager);
621 assert(link->manager->rtnl);
622 assert(callback);
623
624 /* If this is a new address, then refuse adding more than the limit */
625 if (address_get(link, address->family, &address->in_addr, address->prefixlen, NULL) <= 0 &&
626 set_size(link->addresses) >= ADDRESSES_PER_LINK_MAX)
627 return log_link_error_errno(link, SYNTHETIC_ERRNO(E2BIG),
628 "Too many addresses are configured, refusing: %m");
629
630 r = address_acquire(link, address, &address);
631 if (r < 0)
632 return log_link_error_errno(link, r, "Failed to acquire an address from pool: %m");
633
634 if (DEBUG_LOGGING) {
635 _cleanup_free_ char *str = NULL;
636
637 (void) in_addr_to_string(address->family, &address->in_addr, &str);
638 log_link_debug(link, "%s address: %s", update ? "Updating" : "Configuring", strna(str));
639 }
640
641 if (update)
642 r = sd_rtnl_message_new_addr_update(link->manager->rtnl, &req,
643 link->ifindex, address->family);
644 else
645 r = sd_rtnl_message_new_addr(link->manager->rtnl, &req, RTM_NEWADDR,
646 link->ifindex, address->family);
647 if (r < 0)
648 return log_link_error_errno(link, r, "Could not allocate RTM_NEWADDR message: %m");
649
650 r = sd_rtnl_message_addr_set_prefixlen(req, address->prefixlen);
651 if (r < 0)
652 return log_link_error_errno(link, r, "Could not set prefixlen: %m");
653
654 address->flags |= IFA_F_PERMANENT;
655
656 if (address->home_address)
657 address->flags |= IFA_F_HOMEADDRESS;
658
659 if (!FLAGS_SET(address->duplicate_address_detection, ADDRESS_FAMILY_IPV6))
660 address->flags |= IFA_F_NODAD;
661
662 if (address->manage_temporary_address)
663 address->flags |= IFA_F_MANAGETEMPADDR;
664
665 if (!address->prefix_route)
666 address->flags |= IFA_F_NOPREFIXROUTE;
667
668 if (address->autojoin)
669 address->flags |= IFA_F_MCAUTOJOIN;
670
671 r = sd_rtnl_message_addr_set_flags(req, (address->flags & 0xff));
672 if (r < 0)
673 return log_link_error_errno(link, r, "Could not set flags: %m");
674
675 if (address->flags & ~0xff) {
676 r = sd_netlink_message_append_u32(req, IFA_FLAGS, address->flags);
677 if (r < 0)
678 return log_link_error_errno(link, r, "Could not set extended flags: %m");
679 }
680
681 r = sd_rtnl_message_addr_set_scope(req, address->scope);
682 if (r < 0)
683 return log_link_error_errno(link, r, "Could not set scope: %m");
684
685 r = netlink_message_append_in_addr_union(req, IFA_LOCAL, address->family, &address->in_addr);
686 if (r < 0)
687 return log_link_error_errno(link, r, "Could not append IFA_LOCAL attribute: %m");
688
689 if (in_addr_is_null(address->family, &address->in_addr_peer) == 0) {
690 r = netlink_message_append_in_addr_union(req, IFA_ADDRESS, address->family, &address->in_addr_peer);
691 if (r < 0)
692 return log_link_error_errno(link, r, "Could not append IFA_ADDRESS attribute: %m");
693 } else if (address->family == AF_INET && address->prefixlen <= 30) {
694 r = sd_netlink_message_append_in_addr(req, IFA_BROADCAST, &address->broadcast);
695 if (r < 0)
696 return log_link_error_errno(link, r, "Could not append IFA_BROADCAST attribute: %m");
697 }
698
699 if (address->label) {
700 r = sd_netlink_message_append_string(req, IFA_LABEL, address->label);
701 if (r < 0)
702 return log_link_error_errno(link, r, "Could not append IFA_LABEL attribute: %m");
703 }
704
705 r = sd_netlink_message_append_cache_info(req, IFA_CACHEINFO, &address->cinfo);
706 if (r < 0)
707 return log_link_error_errno(link, r, "Could not append IFA_CACHEINFO attribute: %m");
708
709 r = address_establish(address, link);
710 if (r < 0)
711 log_link_warning_errno(link, r, "Could not enable IP masquerading, ignoring: %m");
712
713 r = netlink_call_async(link->manager->rtnl, NULL, req, callback, link_netlink_destroy_callback, link);
714 if (r < 0) {
715 address_release(address);
716 return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
717 }
718
719 link_ref(link);
720
721 if (address->family == AF_INET6 && !in_addr_is_null(address->family, &address->in_addr_peer))
722 r = address_add(link, address->family, &address->in_addr_peer, address->prefixlen, &a);
723 else
724 r = address_add(link, address->family, &address->in_addr, address->prefixlen, &a);
725 if (r < 0) {
726 address_release(address);
727 return log_link_error_errno(link, r, "Could not add address: %m");
728 }
729
730 if (address->acd) {
731 assert(address->family == AF_INET);
732 if (DEBUG_LOGGING) {
733 _cleanup_free_ char *pretty = NULL;
734
735 (void) in_addr_to_string(address->family, &address->in_addr, &pretty);
736 log_link_debug(link, "Starting IPv4ACD client. Probing address %s", strna(pretty));
737 }
738
739 r = sd_ipv4acd_start(address->acd, true);
740 if (r < 0)
741 log_link_warning_errno(link, r, "Failed to start IPv4ACD client, ignoring: %m");
742 }
743
744 if (ret)
745 *ret = a;
746
747 return 1;
748 }
749
750 static void static_address_on_acd(sd_ipv4acd *acd, int event, void *userdata) {
751 _cleanup_free_ char *pretty = NULL;
752 Address *address;
753 Link *link;
754 int r;
755
756 assert(acd);
757 assert(userdata);
758
759 address = (Address *) userdata;
760 link = address->link;
761
762 (void) in_addr_to_string(address->family, &address->in_addr, &pretty);
763 switch (event) {
764 case SD_IPV4ACD_EVENT_STOP:
765 log_link_debug(link, "Stopping ACD client...");
766 return;
767
768 case SD_IPV4ACD_EVENT_BIND:
769 log_link_debug(link, "Successfully claimed address %s", strna(pretty));
770 link_check_ready(link);
771 break;
772
773 case SD_IPV4ACD_EVENT_CONFLICT:
774 log_link_warning(link, "DAD conflict. Dropping address %s", strna(pretty));
775 r = address_remove(address, link, NULL);
776 if (r < 0)
777 log_link_error_errno(link, r, "Failed to drop DAD conflicted address %s", strna(pretty));;
778
779 link_check_ready(link);
780 break;
781
782 default:
783 assert_not_reached("Invalid IPv4ACD event.");
784 }
785
786 sd_ipv4acd_stop(acd);
787
788 return;
789 }
790
791 int configure_ipv4_duplicate_address_detection(Link *link, Address *address) {
792 int r;
793
794 assert(link);
795 assert(address);
796 assert(address->family == AF_INET);
797 assert(!address->link && address->network);
798
799 address->link = link;
800
801 r = sd_ipv4acd_new(&address->acd);
802 if (r < 0)
803 return r;
804
805 r = sd_ipv4acd_attach_event(address->acd, NULL, 0);
806 if (r < 0)
807 return r;
808
809 r = sd_ipv4acd_set_ifindex(address->acd, link->ifindex);
810 if (r < 0)
811 return r;
812
813 r = sd_ipv4acd_set_mac(address->acd, &link->mac);
814 if (r < 0)
815 return r;
816
817 r = sd_ipv4acd_set_address(address->acd, &address->in_addr.in);
818 if (r < 0)
819 return r;
820
821 r = sd_ipv4acd_set_callback(address->acd, static_address_on_acd, address);
822 if (r < 0)
823 return r;
824
825 return 0;
826 }
827
828 int config_parse_broadcast(
829 const char *unit,
830 const char *filename,
831 unsigned line,
832 const char *section,
833 unsigned section_line,
834 const char *lvalue,
835 int ltype,
836 const char *rvalue,
837 void *data,
838 void *userdata) {
839
840 Network *network = userdata;
841 _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
842 int r;
843
844 assert(filename);
845 assert(section);
846 assert(lvalue);
847 assert(rvalue);
848 assert(data);
849
850 r = address_new_static(network, filename, section_line, &n);
851 if (r == -ENOMEM)
852 return log_oom();
853 if (r < 0) {
854 log_syntax(unit, LOG_WARNING, filename, line, r,
855 "Failed to allocate new address, ignoring assignment: %m");
856 return 0;
857 }
858
859 if (n->family == AF_INET6) {
860 log_syntax(unit, LOG_WARNING, filename, line, 0,
861 "Broadcast is not valid for IPv6 addresses, ignoring assignment: %s", rvalue);
862 return 0;
863 }
864
865 r = in_addr_from_string(AF_INET, rvalue, (union in_addr_union*) &n->broadcast);
866 if (r < 0) {
867 log_syntax(unit, LOG_WARNING, filename, line, r,
868 "Broadcast is invalid, ignoring assignment: %s", rvalue);
869 return 0;
870 }
871
872 n->family = AF_INET;
873 n = NULL;
874
875 return 0;
876 }
877
878 int config_parse_address(const char *unit,
879 const char *filename,
880 unsigned line,
881 const char *section,
882 unsigned section_line,
883 const char *lvalue,
884 int ltype,
885 const char *rvalue,
886 void *data,
887 void *userdata) {
888
889 Network *network = userdata;
890 _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
891 union in_addr_union buffer;
892 unsigned char prefixlen;
893 int r, f;
894
895 assert(filename);
896 assert(section);
897 assert(lvalue);
898 assert(rvalue);
899 assert(data);
900
901 if (streq(section, "Network")) {
902 /* we are not in an Address section, so treat
903 * this as the special '0' section */
904 r = address_new_static(network, NULL, 0, &n);
905 } else
906 r = address_new_static(network, filename, section_line, &n);
907 if (r == -ENOMEM)
908 return log_oom();
909 if (r < 0) {
910 log_syntax(unit, LOG_WARNING, filename, line, r,
911 "Failed to allocate new address, ignoring assignment: %m");
912 return 0;
913 }
914
915 /* Address=address/prefixlen */
916 r = in_addr_prefix_from_string_auto_internal(rvalue, PREFIXLEN_REFUSE, &f, &buffer, &prefixlen);
917 if (r == -ENOANO) {
918 log_syntax(unit, LOG_WARNING, filename, line, r,
919 "An address '%s' is specified without prefix length. "
920 "The behavior of parsing addresses without prefix length will be changed in the future release. "
921 "Please specify prefix length explicitly.", rvalue);
922
923 r = in_addr_prefix_from_string_auto_internal(rvalue, PREFIXLEN_LEGACY, &f, &buffer, &prefixlen);
924 }
925 if (r < 0) {
926 log_syntax(unit, LOG_WARNING, filename, line, r, "Invalid address '%s', ignoring assignment: %m", rvalue);
927 return 0;
928 }
929
930 if (n->family != AF_UNSPEC && f != n->family) {
931 log_syntax(unit, LOG_WARNING, filename, line, 0, "Address is incompatible, ignoring assignment: %s", rvalue);
932 return 0;
933 }
934
935 if (in_addr_is_null(f, &buffer)) {
936 /* Will use address from address pool. Note that for ipv6 case, prefix of the address
937 * pool is 8, but 40 bit is used by the global ID and 16 bit by the subnet ID. So,
938 * let's limit the prefix length to 64 or larger. See RFC4193. */
939 if ((f == AF_INET && prefixlen < 8) ||
940 (f == AF_INET6 && prefixlen < 64)) {
941 log_syntax(unit, LOG_WARNING, filename, line, 0,
942 "Null address with invalid prefixlen='%u', ignoring assignment: %s",
943 prefixlen, rvalue);
944 return 0;
945 }
946 }
947
948 n->family = f;
949 n->prefixlen = prefixlen;
950
951 if (streq(lvalue, "Address"))
952 n->in_addr = buffer;
953 else
954 n->in_addr_peer = buffer;
955
956 if (n->family == AF_INET && n->broadcast.s_addr == 0 && n->prefixlen <= 30)
957 n->broadcast.s_addr = n->in_addr.in.s_addr | htobe32(0xfffffffflu >> n->prefixlen);
958
959 n = NULL;
960
961 return 0;
962 }
963
964 int config_parse_label(
965 const char *unit,
966 const char *filename,
967 unsigned line,
968 const char *section,
969 unsigned section_line,
970 const char *lvalue,
971 int ltype,
972 const char *rvalue,
973 void *data,
974 void *userdata) {
975
976 _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
977 Network *network = userdata;
978 int r;
979
980 assert(filename);
981 assert(section);
982 assert(lvalue);
983 assert(rvalue);
984 assert(data);
985
986 r = address_new_static(network, filename, section_line, &n);
987 if (r == -ENOMEM)
988 return log_oom();
989 if (r < 0) {
990 log_syntax(unit, LOG_WARNING, filename, line, r,
991 "Failed to allocate new address, ignoring assignment: %m");
992 return 0;
993 }
994
995 if (!address_label_valid(rvalue)) {
996 log_syntax(unit, LOG_WARNING, filename, line, 0,
997 "Interface label is too long or invalid, ignoring assignment: %s", rvalue);
998 return 0;
999 }
1000
1001 r = free_and_strdup(&n->label, rvalue);
1002 if (r < 0)
1003 return log_oom();
1004
1005 n = NULL;
1006 return 0;
1007 }
1008
1009 int config_parse_lifetime(const char *unit,
1010 const char *filename,
1011 unsigned line,
1012 const char *section,
1013 unsigned section_line,
1014 const char *lvalue,
1015 int ltype,
1016 const char *rvalue,
1017 void *data,
1018 void *userdata) {
1019 Network *network = userdata;
1020 _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
1021 uint32_t k;
1022 int r;
1023
1024 assert(filename);
1025 assert(section);
1026 assert(lvalue);
1027 assert(rvalue);
1028 assert(data);
1029
1030 r = address_new_static(network, filename, section_line, &n);
1031 if (r == -ENOMEM)
1032 return log_oom();
1033 if (r < 0) {
1034 log_syntax(unit, LOG_WARNING, filename, line, r,
1035 "Failed to allocate new address, ignoring assignment: %m");
1036 return 0;
1037 }
1038
1039 /* We accept only "forever", "infinity", empty, or "0". */
1040 if (STR_IN_SET(rvalue, "forever", "infinity", ""))
1041 k = CACHE_INFO_INFINITY_LIFE_TIME;
1042 else if (streq(rvalue, "0"))
1043 k = 0;
1044 else {
1045 log_syntax(unit, LOG_WARNING, filename, line, 0,
1046 "Invalid PreferredLifetime= value, ignoring: %s", rvalue);
1047 return 0;
1048 }
1049
1050 n->cinfo.ifa_prefered = k;
1051 TAKE_PTR(n);
1052
1053 return 0;
1054 }
1055
1056 int config_parse_address_flags(const char *unit,
1057 const char *filename,
1058 unsigned line,
1059 const char *section,
1060 unsigned section_line,
1061 const char *lvalue,
1062 int ltype,
1063 const char *rvalue,
1064 void *data,
1065 void *userdata) {
1066 Network *network = userdata;
1067 _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
1068 int r;
1069
1070 assert(filename);
1071 assert(section);
1072 assert(lvalue);
1073 assert(rvalue);
1074 assert(data);
1075
1076 r = address_new_static(network, filename, section_line, &n);
1077 if (r == -ENOMEM)
1078 return log_oom();
1079 if (r < 0) {
1080 log_syntax(unit, LOG_WARNING, filename, line, r,
1081 "Failed to allocate new address, ignoring assignment: %m");
1082 return 0;
1083 }
1084
1085 r = parse_boolean(rvalue);
1086 if (r < 0) {
1087 log_syntax(unit, LOG_WARNING, filename, line, r,
1088 "Failed to parse %s=, ignoring: %s", lvalue, rvalue);
1089 return 0;
1090 }
1091
1092 if (streq(lvalue, "HomeAddress"))
1093 n->home_address = r;
1094 else if (streq(lvalue, "ManageTemporaryAddress"))
1095 n->manage_temporary_address = r;
1096 else if (streq(lvalue, "PrefixRoute"))
1097 n->prefix_route = !r;
1098 else if (streq(lvalue, "AddPrefixRoute"))
1099 n->prefix_route = r;
1100 else if (streq(lvalue, "AutoJoin"))
1101 n->autojoin = r;
1102 else
1103 assert_not_reached("Invalid address flag type.");
1104
1105 n = NULL;
1106 return 0;
1107 }
1108
1109 int config_parse_address_scope(const char *unit,
1110 const char *filename,
1111 unsigned line,
1112 const char *section,
1113 unsigned section_line,
1114 const char *lvalue,
1115 int ltype,
1116 const char *rvalue,
1117 void *data,
1118 void *userdata) {
1119 Network *network = userdata;
1120 _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
1121 int r;
1122
1123 assert(filename);
1124 assert(section);
1125 assert(lvalue);
1126 assert(rvalue);
1127 assert(data);
1128
1129 r = address_new_static(network, filename, section_line, &n);
1130 if (r == -ENOMEM)
1131 return log_oom();
1132 if (r < 0) {
1133 log_syntax(unit, LOG_WARNING, filename, line, r,
1134 "Failed to allocate new address, ignoring assignment: %m");
1135 return 0;
1136 }
1137
1138 if (streq(rvalue, "host"))
1139 n->scope = RT_SCOPE_HOST;
1140 else if (streq(rvalue, "link"))
1141 n->scope = RT_SCOPE_LINK;
1142 else if (streq(rvalue, "global"))
1143 n->scope = RT_SCOPE_UNIVERSE;
1144 else {
1145 r = safe_atou8(rvalue , &n->scope);
1146 if (r < 0) {
1147 log_syntax(unit, LOG_WARNING, filename, line, r,
1148 "Could not parse address scope \"%s\", ignoring assignment: %m", rvalue);
1149 return 0;
1150 }
1151 }
1152
1153 n->scope_set = true;
1154 n = NULL;
1155 return 0;
1156 }
1157
1158 int config_parse_duplicate_address_detection(
1159 const char *unit,
1160 const char *filename,
1161 unsigned line,
1162 const char *section,
1163 unsigned section_line,
1164 const char *lvalue,
1165 int ltype,
1166 const char *rvalue,
1167 void *data,
1168 void *userdata) {
1169 Network *network = userdata;
1170 _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
1171 AddressFamily a;
1172 int r;
1173
1174 assert(filename);
1175 assert(section);
1176 assert(lvalue);
1177 assert(rvalue);
1178 assert(data);
1179
1180 r = address_new_static(network, filename, section_line, &n);
1181 if (r == -ENOMEM)
1182 return log_oom();
1183 if (r < 0) {
1184 log_syntax(unit, LOG_WARNING, filename, line, r,
1185 "Failed to allocate new address, ignoring assignment: %m");
1186 return 0;
1187 }
1188
1189 r = parse_boolean(rvalue);
1190 if (r >= 0) {
1191 log_syntax(unit, LOG_WARNING, filename, line, 0,
1192 "For historical reasons, %s=%s means %s=%s. "
1193 "Please use 'both', 'ipv4', 'ipv6' or 'none' instead.",
1194 lvalue, rvalue, lvalue, r ? "none" : "both");
1195 n->duplicate_address_detection = r ? ADDRESS_FAMILY_NO : ADDRESS_FAMILY_YES;
1196 n = NULL;
1197 return 0;
1198 }
1199
1200 a = duplicate_address_detection_address_family_from_string(rvalue);
1201 if (a < 0) {
1202 log_syntax(unit, LOG_WARNING, filename, line, SYNTHETIC_ERRNO(EINVAL),
1203 "Failed to parse %s=, ignoring: %s", lvalue, rvalue);
1204 return 0;
1205 }
1206
1207 n->duplicate_address_detection = a;
1208 n = NULL;
1209 return 0;
1210 }
1211
1212 bool address_is_ready(const Address *a) {
1213 assert(a);
1214
1215 return !(a->flags & IFA_F_TENTATIVE);
1216 }
1217
1218 int address_section_verify(Address *address) {
1219 if (section_is_invalid(address->section))
1220 return -EINVAL;
1221
1222 if (address->family == AF_UNSPEC) {
1223 assert(address->section);
1224
1225 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
1226 "%s: Address section without Address= field configured. "
1227 "Ignoring [Address] section from line %u.",
1228 address->section->filename, address->section->line);
1229 }
1230
1231 if (!address->scope_set && in_addr_is_localhost(address->family, &address->in_addr) > 0)
1232 address->scope = RT_SCOPE_HOST;
1233
1234 return 0;
1235 }