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