1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 #pragma once
3 
4 #include <inttypes.h>
5 #include <stdbool.h>
6 #include <stdio.h>
7 
8 #include "sd-ipv4acd.h"
9 
10 #include "conf-parser.h"
11 #include "in-addr-util.h"
12 #include "networkd-link.h"
13 #include "networkd-util.h"
14 #include "time-util.h"
15 
16 typedef struct Address Address;
17 typedef struct Manager Manager;
18 typedef struct Network Network;
19 typedef struct Request Request;
20 typedef int (*address_ready_callback_t)(Address *address);
21 typedef int (*address_netlink_handler_t)(
22                 sd_netlink *rtnl,
23                 sd_netlink_message *m,
24                 Request *req,
25                 Link *link,
26                 Address *address);
27 
28 struct Address {
29         Link *link;
30         Network *network;
31         ConfigSection *section;
32         NetworkConfigSource source;
33         NetworkConfigState state;
34         union in_addr_union provider; /* DHCP server or router address */
35 
36         int family;
37         unsigned char prefixlen;
38         unsigned char scope;
39         uint32_t flags;
40         uint32_t route_metric; /* route metric for prefix route */
41         char *label;
42 
43         int set_broadcast;
44         struct in_addr broadcast;
45 
46         union in_addr_union in_addr;
47         union in_addr_union in_addr_peer;
48 
49         /* These are absolute points in time, and NOT timespans/durations.
50          * Must be specified with clock_boottime_or_monotonic(). */
51         usec_t lifetime_valid_usec;
52         usec_t lifetime_preferred_usec;
53 
54         bool scope_set:1;
55         bool ip_masquerade_done:1;
56 
57         /* duplicate_address_detection is only used by static or IPv4 dynamic addresses.
58          * To control DAD for IPv6 dynamic addresses, set IFA_F_NODAD to flags. */
59         AddressFamily duplicate_address_detection;
60         sd_ipv4acd *acd;
61 
62         /* Called when address become ready */
63         address_ready_callback_t callback;
64 };
65 
66 const char* format_lifetime(char *buf, size_t l, usec_t lifetime_usec) _warn_unused_result_;
67 /* Note: the lifetime of the compound literal is the immediately surrounding block,
68  * see C11 §6.5.2.5, and
69  * https://stackoverflow.com/questions/34880638/compound-literal-lifetime-and-if-blocks */
70 #define FORMAT_LIFETIME(lifetime) \
71         format_lifetime((char[FORMAT_TIMESPAN_MAX+STRLEN("for ")]){}, FORMAT_TIMESPAN_MAX+STRLEN("for "), lifetime)
72 
73 int address_flags_to_string_alloc(uint32_t flags, int family, char **ret);
74 
75 int address_new(Address **ret);
76 Address* address_free(Address *address);
77 int address_get(Link *link, const Address *in, Address **ret);
78 int address_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg);
79 int address_remove(Address *address);
80 int address_dup(const Address *src, Address **ret);
81 bool address_is_ready(const Address *a);
82 void address_set_broadcast(Address *a, Link *link);
83 
84 DEFINE_SECTION_CLEANUP_FUNCTIONS(Address, address_free);
85 
86 int link_drop_managed_addresses(Link *link);
87 int link_drop_foreign_addresses(Link *link);
88 int link_drop_ipv6ll_addresses(Link *link);
89 void link_foreignize_addresses(Link *link);
90 bool link_address_is_dynamic(const Link *link, const Address *address);
91 int link_get_address(Link *link, int family, const union in_addr_union *address, unsigned char prefixlen, Address **ret);
link_get_ipv6_address(Link * link,const struct in6_addr * address,unsigned char prefixlen,Address ** ret)92 static inline int link_get_ipv6_address(Link *link, const struct in6_addr *address, unsigned char prefixlen, Address **ret) {
93         assert(address);
94         return link_get_address(link, AF_INET6, &(union in_addr_union) { .in6 = *address }, prefixlen, ret);
95 }
link_get_ipv4_address(Link * link,const struct in_addr * address,unsigned char prefixlen,Address ** ret)96 static inline int link_get_ipv4_address(Link *link, const struct in_addr *address, unsigned char prefixlen, Address **ret) {
97         assert(address);
98         return link_get_address(link, AF_INET, &(union in_addr_union) { .in = *address }, prefixlen, ret);
99 }
100 int manager_get_address(Manager *manager, int family, const union in_addr_union *address, unsigned char prefixlen, Address **ret);
101 bool manager_has_address(Manager *manager, int family, const union in_addr_union *address, bool check_ready);
102 
103 void address_cancel_request(Address *address);
104 int link_request_address(
105                 Link *link,
106                 Address *address,
107                 bool consume_object,
108                 unsigned *message_counter,
109                 address_netlink_handler_t netlink_handler,
110                 Request **ret);
111 int link_request_static_address(Link *link, Address *address, bool consume);
112 int link_request_static_addresses(Link *link);
113 
114 int manager_rtnl_process_address(sd_netlink *nl, sd_netlink_message *message, Manager *m);
115 
116 int network_drop_invalid_addresses(Network *network);
117 
118 int address_compare_func(const Address *a1, const Address *a2);
119 
120 DEFINE_NETWORK_CONFIG_STATE_FUNCTIONS(Address, address);
address_enter_probing(Address * address)121 static inline void address_enter_probing(Address *address) {
122         address_update_state(address, NETWORK_CONFIG_STATE_PROBING, NETWORK_CONFIG_STATE_PROBING);
123 }
address_cancel_probing(Address * address)124 static inline void address_cancel_probing(Address *address) {
125         address_update_state(address, NETWORK_CONFIG_STATE_PROBING, 0);
126 }
127 
128 void link_mark_addresses(Link *link, NetworkConfigSource source, const struct in6_addr *router);
129 
130 CONFIG_PARSER_PROTOTYPE(config_parse_address);
131 CONFIG_PARSER_PROTOTYPE(config_parse_broadcast);
132 CONFIG_PARSER_PROTOTYPE(config_parse_label);
133 CONFIG_PARSER_PROTOTYPE(config_parse_lifetime);
134 CONFIG_PARSER_PROTOTYPE(config_parse_address_flags);
135 CONFIG_PARSER_PROTOTYPE(config_parse_address_scope);
136 CONFIG_PARSER_PROTOTYPE(config_parse_address_route_metric);
137 CONFIG_PARSER_PROTOTYPE(config_parse_duplicate_address_detection);
138