File: | build-scan/../src/network/networkd-address.c |
Warning: | line 258, column 24 Potential leak of memory pointed to by 'address' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 "netlink-util.h" | |||
9 | #include "networkd-address.h" | |||
10 | #include "networkd-manager.h" | |||
11 | #include "parse-util.h" | |||
12 | #include "set.h" | |||
13 | #include "socket-util.h" | |||
14 | #include "string-util.h" | |||
15 | #include "utf8.h" | |||
16 | #include "util.h" | |||
17 | ||||
18 | #define ADDRESSES_PER_LINK_MAX2048U 2048U | |||
19 | #define STATIC_ADDRESSES_PER_NETWORK_MAX1024U 1024U | |||
20 | ||||
21 | int address_new(Address **ret) { | |||
22 | _cleanup_(address_freep)__attribute__((cleanup(address_freep))) Address *address = NULL((void*)0); | |||
23 | ||||
24 | address = new0(Address, 1)((Address*) calloc((1), sizeof(Address))); | |||
25 | if (!address) | |||
26 | return -ENOMEM12; | |||
27 | ||||
28 | address->family = AF_UNSPEC0; | |||
29 | address->scope = RT_SCOPE_UNIVERSE; | |||
30 | address->cinfo.ifa_prefered = CACHE_INFO_INFINITY_LIFE_TIME0xFFFFFFFFU; | |||
31 | address->cinfo.ifa_valid = CACHE_INFO_INFINITY_LIFE_TIME0xFFFFFFFFU; | |||
32 | ||||
33 | *ret = TAKE_PTR(address)({ typeof(address) _ptr_ = (address); (address) = ((void*)0); _ptr_; }); | |||
34 | ||||
35 | return 0; | |||
36 | } | |||
37 | ||||
38 | int address_new_static(Network *network, const char *filename, unsigned section_line, Address **ret) { | |||
39 | _cleanup_(network_config_section_freep)__attribute__((cleanup(network_config_section_freep))) NetworkConfigSection *n = NULL((void*)0); | |||
40 | _cleanup_(address_freep)__attribute__((cleanup(address_freep))) Address *address = NULL((void*)0); | |||
41 | int r; | |||
42 | ||||
43 | assert(network)do { if ((__builtin_expect(!!(!(network)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("network"), "../src/network/networkd-address.c" , 43, __PRETTY_FUNCTION__); } while (0); | |||
44 | assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("ret"), "../src/network/networkd-address.c" , 44, __PRETTY_FUNCTION__); } while (0); | |||
45 | assert(!!filename == (section_line > 0))do { if ((__builtin_expect(!!(!(!!filename == (section_line > 0))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("!!filename == (section_line > 0)" ), "../src/network/networkd-address.c", 45, __PRETTY_FUNCTION__ ); } while (0); | |||
46 | ||||
47 | if (filename) { | |||
48 | r = network_config_section_new(filename, section_line, &n); | |||
49 | if (r < 0) | |||
50 | return r; | |||
51 | ||||
52 | address = hashmap_get(network->addresses_by_section, n); | |||
53 | if (address) { | |||
54 | *ret = TAKE_PTR(address)({ typeof(address) _ptr_ = (address); (address) = ((void*)0); _ptr_; }); | |||
55 | ||||
56 | return 0; | |||
57 | } | |||
58 | } | |||
59 | ||||
60 | if (network->n_static_addresses >= STATIC_ADDRESSES_PER_NETWORK_MAX1024U) | |||
61 | return -E2BIG7; | |||
62 | ||||
63 | r = address_new(&address); | |||
64 | if (r < 0) | |||
65 | return r; | |||
66 | ||||
67 | if (filename) { | |||
68 | address->section = TAKE_PTR(n)({ typeof(n) _ptr_ = (n); (n) = ((void*)0); _ptr_; }); | |||
69 | ||||
70 | r = hashmap_put(network->addresses_by_section, address->section, address); | |||
71 | if (r < 0) | |||
72 | return r; | |||
73 | } | |||
74 | ||||
75 | address->network = network; | |||
76 | LIST_APPEND(addresses, network->static_addresses, address)do { typeof(*(network->static_addresses)) *_tail; do { typeof (*(network->static_addresses)) *_item = (network->static_addresses ); if (!_item) (_tail) = ((void*)0); else { while (_item-> addresses_next) _item = _item->addresses_next; (_tail) = _item ; } } while (0); do { typeof(*(network->static_addresses)) **_head = &(network->static_addresses), *_a = (_tail) , *_b = (address); do { if ((__builtin_expect(!!(!(_b)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("_b"), "../src/network/networkd-address.c" , 76, __PRETTY_FUNCTION__); } while (0); if (!_a) { if ((_b-> addresses_next = *_head)) _b->addresses_next->addresses_prev = _b; _b->addresses_prev = ((void*)0); *_head = _b; } else { if ((_b->addresses_next = _a->addresses_next)) _b-> addresses_next->addresses_prev = _b; _b->addresses_prev = _a; _a->addresses_next = _b; } } while (0); } while (0); | |||
77 | network->n_static_addresses++; | |||
78 | ||||
79 | *ret = TAKE_PTR(address)({ typeof(address) _ptr_ = (address); (address) = ((void*)0); _ptr_; }); | |||
80 | ||||
81 | return 0; | |||
82 | } | |||
83 | ||||
84 | void address_free(Address *address) { | |||
85 | if (!address) | |||
86 | return; | |||
87 | ||||
88 | if (address->network) { | |||
89 | LIST_REMOVE(addresses, address->network->static_addresses, address)do { typeof(*(address->network->static_addresses)) **_head = &(address->network->static_addresses), *_item = ( address); do { if ((__builtin_expect(!!(!(_item)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("_item"), "../src/network/networkd-address.c" , 89, __PRETTY_FUNCTION__); } while (0); if (_item->addresses_next ) _item->addresses_next->addresses_prev = _item->addresses_prev ; if (_item->addresses_prev) _item->addresses_prev-> addresses_next = _item->addresses_next; else { do { if ((__builtin_expect (!!(!(*_head == _item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD , ("*_head == _item"), "../src/network/networkd-address.c", 89 , __PRETTY_FUNCTION__); } while (0); *_head = _item->addresses_next ; } _item->addresses_next = _item->addresses_prev = ((void *)0); } while (0); | |||
90 | assert(address->network->n_static_addresses > 0)do { if ((__builtin_expect(!!(!(address->network->n_static_addresses > 0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("address->network->n_static_addresses > 0" ), "../src/network/networkd-address.c", 90, __PRETTY_FUNCTION__ ); } while (0); | |||
91 | address->network->n_static_addresses--; | |||
92 | ||||
93 | if (address->section) { | |||
94 | hashmap_remove(address->network->addresses_by_section, address->section); | |||
95 | network_config_section_free(address->section); | |||
96 | } | |||
97 | } | |||
98 | ||||
99 | if (address->link) { | |||
100 | set_remove(address->link->addresses, address); | |||
101 | set_remove(address->link->addresses_foreign, address); | |||
102 | ||||
103 | if (in_addr_equal(AF_INET610, &address->in_addr, (const union in_addr_union *) &address->link->ipv6ll_address)) | |||
104 | memzero(&address->link->ipv6ll_address, sizeof(struct in6_addr))({ size_t _l_ = (sizeof(struct in6_addr)); void *_x_ = (& address->link->ipv6ll_address); _l_ == 0 ? _x_ : memset (_x_, 0, _l_); }); | |||
105 | } | |||
106 | ||||
107 | free(address); | |||
108 | } | |||
109 | ||||
110 | static void address_hash_func(const void *b, struct siphash *state) { | |||
111 | const Address *a = b; | |||
112 | ||||
113 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/network/networkd-address.c" , 113, __PRETTY_FUNCTION__); } while (0); | |||
114 | ||||
115 | siphash24_compress(&a->family, sizeof(a->family), state); | |||
116 | ||||
117 | switch (a->family) { | |||
118 | case AF_INET2: | |||
119 | siphash24_compress(&a->prefixlen, sizeof(a->prefixlen), state); | |||
120 | ||||
121 | /* peer prefix */ | |||
122 | if (a->prefixlen != 0) { | |||
123 | uint32_t prefix; | |||
124 | ||||
125 | if (a->in_addr_peer.in.s_addr != 0) | |||
126 | prefix = be32toh(a->in_addr_peer.in.s_addr) >> (32 - a->prefixlen); | |||
127 | else | |||
128 | prefix = be32toh(a->in_addr.in.s_addr) >> (32 - a->prefixlen); | |||
129 | ||||
130 | siphash24_compress(&prefix, sizeof(prefix), state); | |||
131 | } | |||
132 | ||||
133 | _fallthrough_; | |||
134 | case AF_INET610: | |||
135 | /* local address */ | |||
136 | siphash24_compress(&a->in_addr, FAMILY_ADDRESS_SIZE(a->family), state); | |||
137 | ||||
138 | break; | |||
139 | default: | |||
140 | /* treat any other address family as AF_UNSPEC */ | |||
141 | break; | |||
142 | } | |||
143 | } | |||
144 | ||||
145 | static int address_compare_func(const void *c1, const void *c2) { | |||
146 | const Address *a1 = c1, *a2 = c2; | |||
147 | ||||
148 | if (a1->family < a2->family) | |||
149 | return -1; | |||
150 | if (a1->family > a2->family) | |||
151 | return 1; | |||
152 | ||||
153 | switch (a1->family) { | |||
154 | /* use the same notion of equality as the kernel does */ | |||
155 | case AF_INET2: | |||
156 | if (a1->prefixlen < a2->prefixlen) | |||
157 | return -1; | |||
158 | if (a1->prefixlen > a2->prefixlen) | |||
159 | return 1; | |||
160 | ||||
161 | /* compare the peer prefixes */ | |||
162 | if (a1->prefixlen != 0) { | |||
163 | /* make sure we don't try to shift by 32. | |||
164 | * See ISO/IEC 9899:TC3 ยง 6.5.7.3. */ | |||
165 | uint32_t b1, b2; | |||
166 | ||||
167 | if (a1->in_addr_peer.in.s_addr != 0) | |||
168 | b1 = be32toh(a1->in_addr_peer.in.s_addr) >> (32 - a1->prefixlen); | |||
169 | else | |||
170 | b1 = be32toh(a1->in_addr.in.s_addr) >> (32 - a1->prefixlen); | |||
171 | ||||
172 | if (a2->in_addr_peer.in.s_addr != 0) | |||
173 | b2 = be32toh(a2->in_addr_peer.in.s_addr) >> (32 - a1->prefixlen); | |||
174 | else | |||
175 | b2 = be32toh(a2->in_addr.in.s_addr) >> (32 - a1->prefixlen); | |||
176 | ||||
177 | if (b1 < b2) | |||
178 | return -1; | |||
179 | if (b1 > b2) | |||
180 | return 1; | |||
181 | } | |||
182 | ||||
183 | _fallthrough_; | |||
184 | case AF_INET610: | |||
185 | return memcmp(&a1->in_addr, &a2->in_addr, FAMILY_ADDRESS_SIZE(a1->family)); | |||
186 | default: | |||
187 | /* treat any other address family as AF_UNSPEC */ | |||
188 | return 0; | |||
189 | } | |||
190 | } | |||
191 | ||||
192 | static const struct hash_ops address_hash_ops = { | |||
193 | .hash = address_hash_func, | |||
194 | .compare = address_compare_func | |||
195 | }; | |||
196 | ||||
197 | bool_Bool address_equal(Address *a1, Address *a2) { | |||
198 | if (a1 == a2) | |||
199 | return true1; | |||
200 | ||||
201 | if (!a1 || !a2) | |||
202 | return false0; | |||
203 | ||||
204 | return address_compare_func(a1, a2) == 0; | |||
205 | } | |||
206 | ||||
207 | static int address_establish(Address *address, Link *link) { | |||
208 | bool_Bool masq; | |||
209 | int r; | |||
210 | ||||
211 | assert(address)do { if ((__builtin_expect(!!(!(address)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("address"), "../src/network/networkd-address.c" , 211, __PRETTY_FUNCTION__); } while (0); | |||
212 | assert(link)do { if ((__builtin_expect(!!(!(link)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("link"), "../src/network/networkd-address.c" , 212, __PRETTY_FUNCTION__); } while (0); | |||
213 | ||||
214 | masq = link->network && | |||
215 | link->network->ip_masquerade && | |||
216 | address->family == AF_INET2 && | |||
217 | address->scope < RT_SCOPE_LINK; | |||
218 | ||||
219 | /* Add firewall entry if this is requested */ | |||
220 | if (address->ip_masquerade_done != masq) { | |||
221 | union in_addr_union masked = address->in_addr; | |||
222 | in_addr_mask(address->family, &masked, address->prefixlen); | |||
223 | ||||
224 | r = fw_add_masquerade(masq, AF_INET2, 0, &masked, address->prefixlen, NULL((void*)0), NULL((void*)0), 0); | |||
225 | if (r < 0) | |||
226 | log_link_warning_errno(link, r, "Could not enable IP masquerading: %m")({ const Link *_l = (link); _l ? log_object_internal(4, r, "../src/network/networkd-address.c" , 226, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void *)0), "Could not enable IP masquerading: %m") : log_internal_realm (((LOG_REALM_SYSTEMD) << 10 | ((4))), r, "../src/network/networkd-address.c" , 226, __func__, "Could not enable IP masquerading: %m"); }); | |||
227 | ||||
228 | address->ip_masquerade_done = masq; | |||
229 | } | |||
230 | ||||
231 | return 0; | |||
232 | } | |||
233 | ||||
234 | static int address_add_internal(Link *link, Set **addresses, | |||
235 | int family, | |||
236 | const union in_addr_union *in_addr, | |||
237 | unsigned char prefixlen, | |||
238 | Address **ret) { | |||
239 | _cleanup_(address_freep)__attribute__((cleanup(address_freep))) Address *address = NULL((void*)0); | |||
240 | int r; | |||
241 | ||||
242 | assert(link)do { if ((__builtin_expect(!!(!(link)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("link"), "../src/network/networkd-address.c" , 242, __PRETTY_FUNCTION__); } while (0); | |||
243 | assert(addresses)do { if ((__builtin_expect(!!(!(addresses)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("addresses"), "../src/network/networkd-address.c" , 243, __PRETTY_FUNCTION__); } while (0); | |||
244 | assert(in_addr)do { if ((__builtin_expect(!!(!(in_addr)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("in_addr"), "../src/network/networkd-address.c" , 244, __PRETTY_FUNCTION__); } while (0); | |||
245 | ||||
246 | r = address_new(&address); | |||
247 | if (r
| |||
248 | return r; | |||
249 | ||||
250 | address->family = family; | |||
251 | address->in_addr = *in_addr; | |||
252 | address->prefixlen = prefixlen; | |||
253 | /* Consider address tentative until we get the real flags from the kernel */ | |||
254 | address->flags = IFA_F_TENTATIVE0x40; | |||
255 | ||||
256 | r = set_ensure_allocated(addresses, &address_hash_ops)internal_set_ensure_allocated(addresses, &address_hash_ops ); | |||
257 | if (r < 0) | |||
258 | return r; | |||
| ||||
259 | ||||
260 | r = set_put(*addresses, address); | |||
261 | if (r < 0) | |||
262 | return r; | |||
263 | ||||
264 | address->link = link; | |||
265 | ||||
266 | if (ret) | |||
267 | *ret = address; | |||
268 | ||||
269 | address = NULL((void*)0); | |||
270 | ||||
271 | return 0; | |||
272 | } | |||
273 | ||||
274 | int address_add_foreign(Link *link, int family, const union in_addr_union *in_addr, unsigned char prefixlen, Address **ret) { | |||
275 | return address_add_internal(link, &link->addresses_foreign, family, in_addr, prefixlen, ret); | |||
276 | } | |||
277 | ||||
278 | int address_add(Link *link, int family, const union in_addr_union *in_addr, unsigned char prefixlen, Address **ret) { | |||
279 | Address *address; | |||
280 | int r; | |||
281 | ||||
282 | r = address_get(link, family, in_addr, prefixlen, &address); | |||
283 | if (r == -ENOENT2) { | |||
284 | /* Address does not exist, create a new one */ | |||
285 | r = address_add_internal(link, &link->addresses, family, in_addr, prefixlen, &address); | |||
286 | if (r < 0) | |||
287 | return r; | |||
288 | } else if (r == 0) { | |||
289 | /* Take over a foreign address */ | |||
290 | r = set_ensure_allocated(&link->addresses, &address_hash_ops)internal_set_ensure_allocated(&link->addresses, &address_hash_ops ); | |||
291 | if (r < 0) | |||
292 | return r; | |||
293 | ||||
294 | r = set_put(link->addresses, address); | |||
295 | if (r < 0) | |||
296 | return r; | |||
297 | ||||
298 | set_remove(link->addresses_foreign, address); | |||
299 | } else if (r == 1) { | |||
300 | /* Already exists, do nothing */ | |||
301 | ; | |||
302 | } else | |||
303 | return r; | |||
304 | ||||
305 | if (ret) | |||
306 | *ret = address; | |||
307 | ||||
308 | return 0; | |||
309 | } | |||
310 | ||||
311 | static int address_release(Address *address) { | |||
312 | int r; | |||
313 | ||||
314 | assert(address)do { if ((__builtin_expect(!!(!(address)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("address"), "../src/network/networkd-address.c" , 314, __PRETTY_FUNCTION__); } while (0); | |||
315 | assert(address->link)do { if ((__builtin_expect(!!(!(address->link)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("address->link"), "../src/network/networkd-address.c" , 315, __PRETTY_FUNCTION__); } while (0); | |||
316 | ||||
317 | /* Remove masquerading firewall entry if it was added */ | |||
318 | if (address->ip_masquerade_done) { | |||
319 | union in_addr_union masked = address->in_addr; | |||
320 | in_addr_mask(address->family, &masked, address->prefixlen); | |||
321 | ||||
322 | r = fw_add_masquerade(false0, AF_INET2, 0, &masked, address->prefixlen, NULL((void*)0), NULL((void*)0), 0); | |||
323 | if (r < 0) | |||
324 | log_link_warning_errno(address->link, r, "Failed to disable IP masquerading: %m")({ const Link *_l = (address->link); _l ? log_object_internal (4, r, "../src/network/networkd-address.c", 324, __func__, "INTERFACE=" , _l->ifname, ((void*)0), ((void*)0), "Failed to disable IP masquerading: %m" ) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4 ))), r, "../src/network/networkd-address.c", 324, __func__, "Failed to disable IP masquerading: %m" ); }); | |||
325 | ||||
326 | address->ip_masquerade_done = false0; | |||
327 | } | |||
328 | ||||
329 | return 0; | |||
330 | } | |||
331 | ||||
332 | int address_update( | |||
333 | Address *address, | |||
334 | unsigned char flags, | |||
335 | unsigned char scope, | |||
336 | const struct ifa_cacheinfo *cinfo) { | |||
337 | ||||
338 | bool_Bool ready; | |||
339 | int r; | |||
340 | ||||
341 | assert(address)do { if ((__builtin_expect(!!(!(address)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("address"), "../src/network/networkd-address.c" , 341, __PRETTY_FUNCTION__); } while (0); | |||
342 | assert(cinfo)do { if ((__builtin_expect(!!(!(cinfo)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("cinfo"), "../src/network/networkd-address.c" , 342, __PRETTY_FUNCTION__); } while (0); | |||
343 | assert_return(address->link, 1)do { if (!(((__builtin_expect(!!(address->link),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("address->link" ), "../src/network/networkd-address.c", 343, __PRETTY_FUNCTION__ ), 0))) return (1); } while (0); | |||
344 | ||||
345 | if (IN_SET(address->link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){LINK_STATE_FAILED, LINK_STATE_LINGER})/sizeof (int)]; switch(address->link->state) { case LINK_STATE_FAILED : case LINK_STATE_LINGER: _found = 1; break; default: break; } _found; })) | |||
346 | return 1; | |||
347 | ||||
348 | ready = address_is_ready(address); | |||
349 | ||||
350 | address->flags = flags; | |||
351 | address->scope = scope; | |||
352 | address->cinfo = *cinfo; | |||
353 | ||||
354 | link_update_operstate(address->link); | |||
355 | ||||
356 | if (!ready && address_is_ready(address)) { | |||
357 | link_check_ready(address->link); | |||
358 | ||||
359 | if (address->family == AF_INET610 && | |||
360 | in_addr_is_link_local(AF_INET610, &address->in_addr) > 0 && | |||
361 | in_addr_is_null(AF_INET610, (const union in_addr_union*) &address->link->ipv6ll_address) > 0) { | |||
362 | ||||
363 | r = link_ipv6ll_gained(address->link, &address->in_addr.in6); | |||
364 | if (r < 0) | |||
365 | return r; | |||
366 | } | |||
367 | } | |||
368 | ||||
369 | return 0; | |||
370 | } | |||
371 | ||||
372 | int address_drop(Address *address) { | |||
373 | Link *link; | |||
374 | bool_Bool ready; | |||
375 | ||||
376 | assert(address)do { if ((__builtin_expect(!!(!(address)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("address"), "../src/network/networkd-address.c" , 376, __PRETTY_FUNCTION__); } while (0); | |||
377 | ||||
378 | ready = address_is_ready(address); | |||
379 | link = address->link; | |||
380 | ||||
381 | address_release(address); | |||
382 | address_free(address); | |||
383 | ||||
384 | link_update_operstate(link); | |||
385 | ||||
386 | if (link && !ready) | |||
387 | link_check_ready(link); | |||
388 | ||||
389 | return 0; | |||
390 | } | |||
391 | ||||
392 | int address_get(Link *link, | |||
393 | int family, | |||
394 | const union in_addr_union *in_addr, | |||
395 | unsigned char prefixlen, | |||
396 | Address **ret) { | |||
397 | ||||
398 | Address address, *existing; | |||
399 | ||||
400 | assert(link)do { if ((__builtin_expect(!!(!(link)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("link"), "../src/network/networkd-address.c" , 400, __PRETTY_FUNCTION__); } while (0); | |||
401 | assert(in_addr)do { if ((__builtin_expect(!!(!(in_addr)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("in_addr"), "../src/network/networkd-address.c" , 401, __PRETTY_FUNCTION__); } while (0); | |||
402 | ||||
403 | address = (Address) { | |||
404 | .family = family, | |||
405 | .in_addr = *in_addr, | |||
406 | .prefixlen = prefixlen, | |||
407 | }; | |||
408 | ||||
409 | existing = set_get(link->addresses, &address); | |||
410 | if (existing) { | |||
411 | if (ret) | |||
412 | *ret = existing; | |||
413 | return 1; | |||
414 | } | |||
415 | ||||
416 | existing = set_get(link->addresses_foreign, &address); | |||
417 | if (existing) { | |||
418 | if (ret) | |||
419 | *ret = existing; | |||
420 | return 0; | |||
421 | } | |||
422 | ||||
423 | return -ENOENT2; | |||
424 | } | |||
425 | ||||
426 | int address_remove( | |||
427 | Address *address, | |||
428 | Link *link, | |||
429 | sd_netlink_message_handler_t callback) { | |||
430 | ||||
431 | _cleanup_(sd_netlink_message_unrefp)__attribute__((cleanup(sd_netlink_message_unrefp))) sd_netlink_message *req = NULL((void*)0); | |||
432 | int r; | |||
433 | ||||
434 | assert(address)do { if ((__builtin_expect(!!(!(address)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("address"), "../src/network/networkd-address.c" , 434, __PRETTY_FUNCTION__); } while (0); | |||
435 | assert(IN_SET(address->family, AF_INET, AF_INET6))do { if ((__builtin_expect(!!(!(({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended[20 - sizeof((int[]){2, 10})/sizeof(int)]; switch(address->family ) { case 2: case 10: _found = 1; break; default: break; } _found ; }))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("IN_SET(address->family, AF_INET, AF_INET6)" ), "../src/network/networkd-address.c", 435, __PRETTY_FUNCTION__ ); } while (0); | |||
436 | assert(link)do { if ((__builtin_expect(!!(!(link)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("link"), "../src/network/networkd-address.c" , 436, __PRETTY_FUNCTION__); } while (0); | |||
437 | assert(link->ifindex > 0)do { if ((__builtin_expect(!!(!(link->ifindex > 0)),0)) ) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("link->ifindex > 0" ), "../src/network/networkd-address.c", 437, __PRETTY_FUNCTION__ ); } while (0); | |||
438 | assert(link->manager)do { if ((__builtin_expect(!!(!(link->manager)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("link->manager"), "../src/network/networkd-address.c" , 438, __PRETTY_FUNCTION__); } while (0); | |||
439 | assert(link->manager->rtnl)do { if ((__builtin_expect(!!(!(link->manager->rtnl)),0 ))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("link->manager->rtnl" ), "../src/network/networkd-address.c", 439, __PRETTY_FUNCTION__ ); } while (0); | |||
440 | ||||
441 | r = sd_rtnl_message_new_addr(link->manager->rtnl, &req, RTM_DELADDRRTM_DELADDR, | |||
442 | link->ifindex, address->family); | |||
443 | if (r < 0) | |||
444 | return log_error_errno(r, "Could not allocate RTM_DELADDR message: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-address.c", 444, __func__, "Could not allocate RTM_DELADDR message: %m" ) : -abs(_e); }); | |||
445 | ||||
446 | r = sd_rtnl_message_addr_set_prefixlen(req, address->prefixlen); | |||
447 | if (r < 0) | |||
448 | return log_error_errno(r, "Could not set prefixlen: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-address.c", 448, __func__, "Could not set prefixlen: %m" ) : -abs(_e); }); | |||
449 | ||||
450 | if (address->family == AF_INET2) | |||
451 | r = sd_netlink_message_append_in_addr(req, IFA_LOCAL, &address->in_addr.in); | |||
452 | else if (address->family == AF_INET610) | |||
453 | r = sd_netlink_message_append_in6_addr(req, IFA_LOCAL, &address->in_addr.in6); | |||
454 | if (r < 0) | |||
455 | return log_error_errno(r, "Could not append IFA_LOCAL attribute: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-address.c", 455, __func__, "Could not append IFA_LOCAL attribute: %m" ) : -abs(_e); }); | |||
456 | ||||
457 | r = sd_netlink_call_async(link->manager->rtnl, req, callback, link, 0, NULL((void*)0)); | |||
458 | if (r < 0) | |||
459 | return log_error_errno(r, "Could not send rtnetlink message: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-address.c", 459, __func__, "Could not send rtnetlink message: %m" ) : -abs(_e); }); | |||
460 | ||||
461 | link_ref(link); | |||
462 | ||||
463 | return 0; | |||
464 | } | |||
465 | ||||
466 | static int address_acquire(Link *link, Address *original, Address **ret) { | |||
467 | union in_addr_union in_addr = {}; | |||
468 | struct in_addr broadcast = {}; | |||
469 | _cleanup_(address_freep)__attribute__((cleanup(address_freep))) Address *na = NULL((void*)0); | |||
470 | int r; | |||
471 | ||||
472 | assert(link)do { if ((__builtin_expect(!!(!(link)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("link"), "../src/network/networkd-address.c" , 472, __PRETTY_FUNCTION__); } while (0); | |||
473 | assert(original)do { if ((__builtin_expect(!!(!(original)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("original"), "../src/network/networkd-address.c" , 473, __PRETTY_FUNCTION__); } while (0); | |||
474 | assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("ret"), "../src/network/networkd-address.c" , 474, __PRETTY_FUNCTION__); } while (0); | |||
475 | ||||
476 | /* Something useful was configured? just use it */ | |||
477 | if (in_addr_is_null(original->family, &original->in_addr) <= 0) | |||
478 | return 0; | |||
479 | ||||
480 | /* The address is configured to be 0.0.0.0 or [::] by the user? | |||
481 | * Then let's acquire something more useful from the pool. */ | |||
482 | r = manager_address_pool_acquire(link->manager, original->family, original->prefixlen, &in_addr); | |||
483 | if (r < 0) | |||
484 | return log_link_error_errno(link, r, "Failed to acquire address from pool: %m")({ const Link *_l = (link); _l ? log_object_internal(3, r, "../src/network/networkd-address.c" , 484, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void *)0), "Failed to acquire address from pool: %m") : log_internal_realm (((LOG_REALM_SYSTEMD) << 10 | ((3))), r, "../src/network/networkd-address.c" , 484, __func__, "Failed to acquire address from pool: %m"); } ); | |||
485 | if (r == 0) { | |||
486 | log_link_error(link, "Couldn't find free address for interface, all taken.")({ const Link *_l = (link); _l ? log_object_internal(3, 0, "../src/network/networkd-address.c" , 486, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void *)0), "Couldn't find free address for interface, all taken.") : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3) )), 0, "../src/network/networkd-address.c", 486, __func__, "Couldn't find free address for interface, all taken." ); }); | |||
487 | return -EBUSY16; | |||
488 | } | |||
489 | ||||
490 | if (original->family == AF_INET2) { | |||
491 | /* Pick first address in range for ourselves ... */ | |||
492 | in_addr.in.s_addr = in_addr.in.s_addr | htobe32(1); | |||
493 | ||||
494 | /* .. and use last as broadcast address */ | |||
495 | if (original->prefixlen > 30) | |||
496 | broadcast.s_addr = 0; | |||
497 | else | |||
498 | broadcast.s_addr = in_addr.in.s_addr | htobe32(0xFFFFFFFFUL >> original->prefixlen); | |||
499 | } else if (original->family == AF_INET610) | |||
500 | in_addr.in6.s6_addr__in6_u.__u6_addr8[15] |= 1; | |||
501 | ||||
502 | r = address_new(&na); | |||
503 | if (r < 0) | |||
504 | return r; | |||
505 | ||||
506 | na->family = original->family; | |||
507 | na->prefixlen = original->prefixlen; | |||
508 | na->scope = original->scope; | |||
509 | na->cinfo = original->cinfo; | |||
510 | ||||
511 | if (original->label) { | |||
512 | na->label = strdup(original->label); | |||
513 | if (!na->label) | |||
514 | return -ENOMEM12; | |||
515 | } | |||
516 | ||||
517 | na->broadcast = broadcast; | |||
518 | na->in_addr = in_addr; | |||
519 | ||||
520 | LIST_PREPEND(addresses, link->pool_addresses, na)do { typeof(*(link->pool_addresses)) **_head = &(link-> pool_addresses), *_item = (na); do { if ((__builtin_expect(!! (!(_item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("_item" ), "../src/network/networkd-address.c", 520, __PRETTY_FUNCTION__ ); } while (0); if ((_item->addresses_next = *_head)) _item ->addresses_next->addresses_prev = _item; _item->addresses_prev = ((void*)0); *_head = _item; } while (0); | |||
521 | ||||
522 | *ret = TAKE_PTR(na)({ typeof(na) _ptr_ = (na); (na) = ((void*)0); _ptr_; }); | |||
523 | ||||
524 | return 0; | |||
525 | } | |||
526 | ||||
527 | int address_configure( | |||
528 | Address *address, | |||
529 | Link *link, | |||
530 | sd_netlink_message_handler_t callback, | |||
531 | bool_Bool update) { | |||
532 | ||||
533 | _cleanup_(sd_netlink_message_unrefp)__attribute__((cleanup(sd_netlink_message_unrefp))) sd_netlink_message *req = NULL((void*)0); | |||
534 | int r; | |||
535 | ||||
536 | assert(address)do { if ((__builtin_expect(!!(!(address)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("address"), "../src/network/networkd-address.c" , 536, __PRETTY_FUNCTION__); } while (0); | |||
| ||||
537 | assert(IN_SET(address->family, AF_INET, AF_INET6))do { if ((__builtin_expect(!!(!(({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended[20 - sizeof((int[]){2, 10})/sizeof(int)]; switch(address->family ) { case 2: case 10: _found = 1; break; default: break; } _found ; }))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("IN_SET(address->family, AF_INET, AF_INET6)" ), "../src/network/networkd-address.c", 537, __PRETTY_FUNCTION__ ); } while (0); | |||
538 | assert(link)do { if ((__builtin_expect(!!(!(link)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("link"), "../src/network/networkd-address.c" , 538, __PRETTY_FUNCTION__); } while (0); | |||
539 | assert(link->ifindex > 0)do { if ((__builtin_expect(!!(!(link->ifindex > 0)),0)) ) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("link->ifindex > 0" ), "../src/network/networkd-address.c", 539, __PRETTY_FUNCTION__ ); } while (0); | |||
540 | assert(link->manager)do { if ((__builtin_expect(!!(!(link->manager)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("link->manager"), "../src/network/networkd-address.c" , 540, __PRETTY_FUNCTION__); } while (0); | |||
541 | assert(link->manager->rtnl)do { if ((__builtin_expect(!!(!(link->manager->rtnl)),0 ))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("link->manager->rtnl" ), "../src/network/networkd-address.c", 541, __PRETTY_FUNCTION__ ); } while (0); | |||
542 | ||||
543 | /* If this is a new address, then refuse adding more than the limit */ | |||
544 | if (address_get(link, address->family, &address->in_addr, address->prefixlen, NULL((void*)0)) <= 0 && | |||
545 | set_size(link->addresses) >= ADDRESSES_PER_LINK_MAX2048U) | |||
546 | return -E2BIG7; | |||
547 | ||||
548 | r = address_acquire(link, address, &address); | |||
549 | if (r < 0) | |||
550 | return r; | |||
551 | ||||
552 | if (update) | |||
553 | r = sd_rtnl_message_new_addr_update(link->manager->rtnl, &req, | |||
554 | link->ifindex, address->family); | |||
555 | else | |||
556 | r = sd_rtnl_message_new_addr(link->manager->rtnl, &req, RTM_NEWADDRRTM_NEWADDR, | |||
557 | link->ifindex, address->family); | |||
558 | if (r < 0) | |||
559 | return log_error_errno(r, "Could not allocate RTM_NEWADDR message: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-address.c", 559, __func__, "Could not allocate RTM_NEWADDR message: %m" ) : -abs(_e); }); | |||
560 | ||||
561 | r = sd_rtnl_message_addr_set_prefixlen(req, address->prefixlen); | |||
562 | if (r < 0) | |||
563 | return log_error_errno(r, "Could not set prefixlen: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-address.c", 563, __func__, "Could not set prefixlen: %m" ) : -abs(_e); }); | |||
564 | ||||
565 | address->flags |= IFA_F_PERMANENT0x80; | |||
566 | ||||
567 | if (address->home_address) | |||
568 | address->flags |= IFA_F_HOMEADDRESS0x10; | |||
569 | ||||
570 | if (address->duplicate_address_detection) | |||
571 | address->flags |= IFA_F_NODAD0x02; | |||
572 | ||||
573 | if (address->manage_temporary_address) | |||
574 | address->flags |= IFA_F_MANAGETEMPADDR0x100; | |||
575 | ||||
576 | if (address->prefix_route) | |||
577 | address->flags |= IFA_F_NOPREFIXROUTE0x200; | |||
578 | ||||
579 | if (address->autojoin) | |||
580 | address->flags |= IFA_F_MCAUTOJOIN0x400; | |||
581 | ||||
582 | r = sd_rtnl_message_addr_set_flags(req, (address->flags & 0xff)); | |||
583 | if (r < 0) | |||
584 | return log_error_errno(r, "Could not set flags: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-address.c", 584, __func__, "Could not set flags: %m" ) : -abs(_e); }); | |||
585 | ||||
586 | if (address->flags & ~0xff) { | |||
587 | r = sd_netlink_message_append_u32(req, IFA_FLAGS, address->flags); | |||
588 | if (r < 0) | |||
589 | return log_error_errno(r, "Could not set extended flags: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-address.c", 589, __func__, "Could not set extended flags: %m" ) : -abs(_e); }); | |||
590 | } | |||
591 | ||||
592 | r = sd_rtnl_message_addr_set_scope(req, address->scope); | |||
593 | if (r < 0) | |||
594 | return log_error_errno(r, "Could not set scope: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-address.c", 594, __func__, "Could not set scope: %m" ) : -abs(_e); }); | |||
595 | ||||
596 | if (address->family
| |||
597 | r = sd_netlink_message_append_in_addr(req, IFA_LOCAL, &address->in_addr.in); | |||
598 | else if (address->family == AF_INET610) | |||
599 | r = sd_netlink_message_append_in6_addr(req, IFA_LOCAL, &address->in_addr.in6); | |||
600 | if (r < 0) | |||
601 | return log_error_errno(r, "Could not append IFA_LOCAL attribute: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-address.c", 601, __func__, "Could not append IFA_LOCAL attribute: %m" ) : -abs(_e); }); | |||
602 | ||||
603 | if (!in_addr_is_null(address->family, &address->in_addr_peer)) { | |||
604 | if (address->family
| |||
605 | r = sd_netlink_message_append_in_addr(req, IFA_ADDRESS, &address->in_addr_peer.in); | |||
606 | else if (address->family == AF_INET610) | |||
607 | r = sd_netlink_message_append_in6_addr(req, IFA_ADDRESS, &address->in_addr_peer.in6); | |||
608 | if (r < 0) | |||
609 | return log_error_errno(r, "Could not append IFA_ADDRESS attribute: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-address.c", 609, __func__, "Could not append IFA_ADDRESS attribute: %m" ) : -abs(_e); }); | |||
610 | } else { | |||
611 | if (address->family == AF_INET2) { | |||
612 | if (address->prefixlen <= 30) { | |||
613 | r = sd_netlink_message_append_in_addr(req, IFA_BROADCAST, &address->broadcast); | |||
614 | if (r < 0) | |||
615 | return log_error_errno(r, "Could not append IFA_BROADCAST attribute: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-address.c", 615, __func__, "Could not append IFA_BROADCAST attribute: %m" ) : -abs(_e); }); | |||
616 | } | |||
617 | } | |||
618 | } | |||
619 | ||||
620 | if (address->label) { | |||
621 | r = sd_netlink_message_append_string(req, IFA_LABEL, address->label); | |||
622 | if (r < 0) | |||
623 | return log_error_errno(r, "Could not append IFA_LABEL attribute: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-address.c", 623, __func__, "Could not append IFA_LABEL attribute: %m" ) : -abs(_e); }); | |||
624 | } | |||
625 | ||||
626 | r = sd_netlink_message_append_cache_info(req, IFA_CACHEINFO, | |||
627 | &address->cinfo); | |||
628 | if (r < 0) | |||
629 | return log_error_errno(r, "Could not append IFA_CACHEINFO attribute: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-address.c", 629, __func__, "Could not append IFA_CACHEINFO attribute: %m" ) : -abs(_e); }); | |||
630 | ||||
631 | r = address_establish(address, link); | |||
632 | if (r < 0) | |||
633 | return r; | |||
634 | ||||
635 | r = sd_netlink_call_async(link->manager->rtnl, req, callback, link, 0, NULL((void*)0)); | |||
636 | if (r < 0) { | |||
637 | address_release(address); | |||
638 | return log_error_errno(r, "Could not send rtnetlink message: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-address.c", 638, __func__, "Could not send rtnetlink message: %m" ) : -abs(_e); }); | |||
639 | } | |||
640 | ||||
641 | link_ref(link); | |||
642 | ||||
643 | r = address_add(link, address->family, &address->in_addr, address->prefixlen, NULL((void*)0)); | |||
644 | if (r < 0) { | |||
645 | address_release(address); | |||
646 | return log_error_errno(r, "Could not add address: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-address.c", 646, __func__, "Could not add address: %m" ) : -abs(_e); }); | |||
647 | } | |||
648 | ||||
649 | return 0; | |||
650 | } | |||
651 | ||||
652 | int config_parse_broadcast( | |||
653 | const char *unit, | |||
654 | const char *filename, | |||
655 | unsigned line, | |||
656 | const char *section, | |||
657 | unsigned section_line, | |||
658 | const char *lvalue, | |||
659 | int ltype, | |||
660 | const char *rvalue, | |||
661 | void *data, | |||
662 | void *userdata) { | |||
663 | ||||
664 | Network *network = userdata; | |||
665 | _cleanup_(address_freep)__attribute__((cleanup(address_freep))) Address *n = NULL((void*)0); | |||
666 | int r; | |||
667 | ||||
668 | assert(filename)do { if ((__builtin_expect(!!(!(filename)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("filename"), "../src/network/networkd-address.c" , 668, __PRETTY_FUNCTION__); } while (0); | |||
669 | assert(section)do { if ((__builtin_expect(!!(!(section)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("section"), "../src/network/networkd-address.c" , 669, __PRETTY_FUNCTION__); } while (0); | |||
670 | assert(lvalue)do { if ((__builtin_expect(!!(!(lvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("lvalue"), "../src/network/networkd-address.c" , 670, __PRETTY_FUNCTION__); } while (0); | |||
671 | assert(rvalue)do { if ((__builtin_expect(!!(!(rvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("rvalue"), "../src/network/networkd-address.c" , 671, __PRETTY_FUNCTION__); } while (0); | |||
672 | assert(data)do { if ((__builtin_expect(!!(!(data)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("data"), "../src/network/networkd-address.c" , 672, __PRETTY_FUNCTION__); } while (0); | |||
673 | ||||
674 | r = address_new_static(network, filename, section_line, &n); | |||
675 | if (r < 0) | |||
676 | return r; | |||
677 | ||||
678 | if (n->family == AF_INET610) { | |||
679 | log_syntax(unit, LOG_ERR, filename, line, 0, "Broadcast is not valid for IPv6 addresses, ignoring assignment: %s", rvalue)({ int _level = (3), _e = (0); (log_get_max_level_realm(LOG_REALM_SYSTEMD ) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level , filename, line, _e, "../src/network/networkd-address.c", 679 , __func__, "Broadcast is not valid for IPv6 addresses, ignoring assignment: %s" , rvalue) : -abs(_e); }); | |||
680 | return 0; | |||
681 | } | |||
682 | ||||
683 | r = in_addr_from_string(AF_INET2, rvalue, (union in_addr_union*) &n->broadcast); | |||
684 | if (r < 0) { | |||
685 | log_syntax(unit, LOG_ERR, filename, line, r, "Broadcast is invalid, ignoring assignment: %s", rvalue)({ int _level = (3), _e = (r); (log_get_max_level_realm(LOG_REALM_SYSTEMD ) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level , filename, line, _e, "../src/network/networkd-address.c", 685 , __func__, "Broadcast is invalid, ignoring assignment: %s", rvalue ) : -abs(_e); }); | |||
686 | return 0; | |||
687 | } | |||
688 | ||||
689 | n->family = AF_INET2; | |||
690 | n = NULL((void*)0); | |||
691 | ||||
692 | return 0; | |||
693 | } | |||
694 | ||||
695 | int config_parse_address(const char *unit, | |||
696 | const char *filename, | |||
697 | unsigned line, | |||
698 | const char *section, | |||
699 | unsigned section_line, | |||
700 | const char *lvalue, | |||
701 | int ltype, | |||
702 | const char *rvalue, | |||
703 | void *data, | |||
704 | void *userdata) { | |||
705 | ||||
706 | Network *network = userdata; | |||
707 | _cleanup_(address_freep)__attribute__((cleanup(address_freep))) Address *n = NULL((void*)0); | |||
708 | const char *address, *e; | |||
709 | union in_addr_union buffer; | |||
710 | int r, f; | |||
711 | ||||
712 | assert(filename)do { if ((__builtin_expect(!!(!(filename)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("filename"), "../src/network/networkd-address.c" , 712, __PRETTY_FUNCTION__); } while (0); | |||
713 | assert(section)do { if ((__builtin_expect(!!(!(section)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("section"), "../src/network/networkd-address.c" , 713, __PRETTY_FUNCTION__); } while (0); | |||
714 | assert(lvalue)do { if ((__builtin_expect(!!(!(lvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("lvalue"), "../src/network/networkd-address.c" , 714, __PRETTY_FUNCTION__); } while (0); | |||
715 | assert(rvalue)do { if ((__builtin_expect(!!(!(rvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("rvalue"), "../src/network/networkd-address.c" , 715, __PRETTY_FUNCTION__); } while (0); | |||
716 | assert(data)do { if ((__builtin_expect(!!(!(data)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("data"), "../src/network/networkd-address.c" , 716, __PRETTY_FUNCTION__); } while (0); | |||
717 | ||||
718 | if (streq(section, "Network")(strcmp((section),("Network")) == 0)) { | |||
719 | /* we are not in an Address section, so treat | |||
720 | * this as the special '0' section */ | |||
721 | r = address_new_static(network, NULL((void*)0), 0, &n); | |||
722 | } else | |||
723 | r = address_new_static(network, filename, section_line, &n); | |||
724 | ||||
725 | if (r < 0) | |||
726 | return r; | |||
727 | ||||
728 | /* Address=address/prefixlen */ | |||
729 | ||||
730 | /* prefixlen */ | |||
731 | e = strchr(rvalue, '/'); | |||
732 | if (e) { | |||
733 | unsigned i; | |||
734 | ||||
735 | r = safe_atou(e + 1, &i); | |||
736 | if (r < 0) { | |||
737 | log_syntax(unit, LOG_ERR, filename, line, r, "Prefix length is invalid, ignoring assignment: %s", e + 1)({ int _level = (3), _e = (r); (log_get_max_level_realm(LOG_REALM_SYSTEMD ) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level , filename, line, _e, "../src/network/networkd-address.c", 737 , __func__, "Prefix length is invalid, ignoring assignment: %s" , e + 1) : -abs(_e); }); | |||
738 | return 0; | |||
739 | } | |||
740 | ||||
741 | n->prefixlen = (unsigned char) i; | |||
742 | ||||
743 | address = strndupa(rvalue, e - rvalue)(__extension__ ({ const char *__old = (rvalue); size_t __len = strnlen (__old, (e - rvalue)); char *__new = (char *) __builtin_alloca (__len + 1); __new[__len] = '\0'; (char *) memcpy (__new, __old , __len); })); | |||
744 | } else | |||
745 | address = rvalue; | |||
746 | ||||
747 | r = in_addr_from_string_auto(address, &f, &buffer); | |||
748 | if (r < 0) { | |||
749 | log_syntax(unit, LOG_ERR, filename, line, r, "Address is invalid, ignoring assignment: %s", address)({ int _level = (3), _e = (r); (log_get_max_level_realm(LOG_REALM_SYSTEMD ) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level , filename, line, _e, "../src/network/networkd-address.c", 749 , __func__, "Address is invalid, ignoring assignment: %s", address ) : -abs(_e); }); | |||
750 | return 0; | |||
751 | } | |||
752 | ||||
753 | if (!e && f == AF_INET2) { | |||
754 | r = in4_addr_default_prefixlen(&buffer.in, &n->prefixlen); | |||
755 | if (r < 0) { | |||
756 | log_syntax(unit, LOG_ERR, filename, line, r, "Prefix length not specified, and a default one cannot be deduced for '%s', ignoring assignment", address)({ int _level = (3), _e = (r); (log_get_max_level_realm(LOG_REALM_SYSTEMD ) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level , filename, line, _e, "../src/network/networkd-address.c", 756 , __func__, "Prefix length not specified, and a default one cannot be deduced for '%s', ignoring assignment" , address) : -abs(_e); }); | |||
757 | return 0; | |||
758 | } | |||
759 | } | |||
760 | ||||
761 | if (n->family != AF_UNSPEC0 && f != n->family) { | |||
762 | log_syntax(unit, LOG_ERR, filename, line, 0, "Address is incompatible, ignoring assignment: %s", address)({ int _level = (3), _e = (0); (log_get_max_level_realm(LOG_REALM_SYSTEMD ) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level , filename, line, _e, "../src/network/networkd-address.c", 762 , __func__, "Address is incompatible, ignoring assignment: %s" , address) : -abs(_e); }); | |||
763 | return 0; | |||
764 | } | |||
765 | ||||
766 | n->family = f; | |||
767 | ||||
768 | if (streq(lvalue, "Address")(strcmp((lvalue),("Address")) == 0)) | |||
769 | n->in_addr = buffer; | |||
770 | else | |||
771 | n->in_addr_peer = buffer; | |||
772 | ||||
773 | if (n->family == AF_INET2 && n->broadcast.s_addr == 0) | |||
774 | n->broadcast.s_addr = n->in_addr.in.s_addr | htonl(0xfffffffflu >> n->prefixlen); | |||
775 | ||||
776 | n = NULL((void*)0); | |||
777 | ||||
778 | return 0; | |||
779 | } | |||
780 | ||||
781 | int config_parse_label( | |||
782 | const char *unit, | |||
783 | const char *filename, | |||
784 | unsigned line, | |||
785 | const char *section, | |||
786 | unsigned section_line, | |||
787 | const char *lvalue, | |||
788 | int ltype, | |||
789 | const char *rvalue, | |||
790 | void *data, | |||
791 | void *userdata) { | |||
792 | ||||
793 | _cleanup_(address_freep)__attribute__((cleanup(address_freep))) Address *n = NULL((void*)0); | |||
794 | Network *network = userdata; | |||
795 | int r; | |||
796 | ||||
797 | assert(filename)do { if ((__builtin_expect(!!(!(filename)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("filename"), "../src/network/networkd-address.c" , 797, __PRETTY_FUNCTION__); } while (0); | |||
798 | assert(section)do { if ((__builtin_expect(!!(!(section)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("section"), "../src/network/networkd-address.c" , 798, __PRETTY_FUNCTION__); } while (0); | |||
799 | assert(lvalue)do { if ((__builtin_expect(!!(!(lvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("lvalue"), "../src/network/networkd-address.c" , 799, __PRETTY_FUNCTION__); } while (0); | |||
800 | assert(rvalue)do { if ((__builtin_expect(!!(!(rvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("rvalue"), "../src/network/networkd-address.c" , 800, __PRETTY_FUNCTION__); } while (0); | |||
801 | assert(data)do { if ((__builtin_expect(!!(!(data)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("data"), "../src/network/networkd-address.c" , 801, __PRETTY_FUNCTION__); } while (0); | |||
802 | ||||
803 | r = address_new_static(network, filename, section_line, &n); | |||
804 | if (r < 0) | |||
805 | return r; | |||
806 | ||||
807 | if (!address_label_valid(rvalue)) { | |||
808 | log_syntax(unit, LOG_ERR, filename, line, 0, "Interface label is too long or invalid, ignoring assignment: %s", rvalue)({ int _level = (3), _e = (0); (log_get_max_level_realm(LOG_REALM_SYSTEMD ) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level , filename, line, _e, "../src/network/networkd-address.c", 808 , __func__, "Interface label is too long or invalid, ignoring assignment: %s" , rvalue) : -abs(_e); }); | |||
809 | return 0; | |||
810 | } | |||
811 | ||||
812 | r = free_and_strdup(&n->label, rvalue); | |||
813 | if (r < 0) | |||
814 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/network/networkd-address.c" , 814, __func__); | |||
815 | ||||
816 | n = NULL((void*)0); | |||
817 | ||||
818 | return 0; | |||
819 | } | |||
820 | ||||
821 | int config_parse_lifetime(const char *unit, | |||
822 | const char *filename, | |||
823 | unsigned line, | |||
824 | const char *section, | |||
825 | unsigned section_line, | |||
826 | const char *lvalue, | |||
827 | int ltype, | |||
828 | const char *rvalue, | |||
829 | void *data, | |||
830 | void *userdata) { | |||
831 | Network *network = userdata; | |||
832 | _cleanup_(address_freep)__attribute__((cleanup(address_freep))) Address *n = NULL((void*)0); | |||
833 | unsigned k; | |||
834 | int r; | |||
835 | ||||
836 | assert(filename)do { if ((__builtin_expect(!!(!(filename)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("filename"), "../src/network/networkd-address.c" , 836, __PRETTY_FUNCTION__); } while (0); | |||
837 | assert(section)do { if ((__builtin_expect(!!(!(section)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("section"), "../src/network/networkd-address.c" , 837, __PRETTY_FUNCTION__); } while (0); | |||
838 | assert(lvalue)do { if ((__builtin_expect(!!(!(lvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("lvalue"), "../src/network/networkd-address.c" , 838, __PRETTY_FUNCTION__); } while (0); | |||
839 | assert(rvalue)do { if ((__builtin_expect(!!(!(rvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("rvalue"), "../src/network/networkd-address.c" , 839, __PRETTY_FUNCTION__); } while (0); | |||
840 | assert(data)do { if ((__builtin_expect(!!(!(data)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("data"), "../src/network/networkd-address.c" , 840, __PRETTY_FUNCTION__); } while (0); | |||
841 | ||||
842 | r = address_new_static(network, filename, section_line, &n); | |||
843 | if (r < 0) | |||
844 | return r; | |||
845 | ||||
846 | if (STR_IN_SET(rvalue, "forever", "infinity")(!!strv_find((((char**) ((const char*[]) { "forever", "infinity" , ((void*)0) }))), (rvalue)))) { | |||
847 | n->cinfo.ifa_prefered = CACHE_INFO_INFINITY_LIFE_TIME0xFFFFFFFFU; | |||
848 | n = NULL((void*)0); | |||
849 | ||||
850 | return 0; | |||
851 | } | |||
852 | ||||
853 | r = safe_atou(rvalue, &k); | |||
854 | if (r < 0) { | |||
855 | log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse PreferredLifetime, ignoring: %s", rvalue)({ int _level = (3), _e = (r); (log_get_max_level_realm(LOG_REALM_SYSTEMD ) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level , filename, line, _e, "../src/network/networkd-address.c", 855 , __func__, "Failed to parse PreferredLifetime, ignoring: %s" , rvalue) : -abs(_e); }); | |||
856 | return 0; | |||
857 | } | |||
858 | ||||
859 | if (k != 0) | |||
860 | log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid PreferredLifetime value, ignoring: %d", k)({ int _level = (3), _e = (0); (log_get_max_level_realm(LOG_REALM_SYSTEMD ) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level , filename, line, _e, "../src/network/networkd-address.c", 860 , __func__, "Invalid PreferredLifetime value, ignoring: %d", k ) : -abs(_e); }); | |||
861 | else { | |||
862 | n->cinfo.ifa_prefered = k; | |||
863 | n = NULL((void*)0); | |||
864 | } | |||
865 | ||||
866 | return 0; | |||
867 | } | |||
868 | ||||
869 | int config_parse_address_flags(const char *unit, | |||
870 | const char *filename, | |||
871 | unsigned line, | |||
872 | const char *section, | |||
873 | unsigned section_line, | |||
874 | const char *lvalue, | |||
875 | int ltype, | |||
876 | const char *rvalue, | |||
877 | void *data, | |||
878 | void *userdata) { | |||
879 | Network *network = userdata; | |||
880 | _cleanup_(address_freep)__attribute__((cleanup(address_freep))) Address *n = NULL((void*)0); | |||
881 | int r; | |||
882 | ||||
883 | assert(filename)do { if ((__builtin_expect(!!(!(filename)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("filename"), "../src/network/networkd-address.c" , 883, __PRETTY_FUNCTION__); } while (0); | |||
884 | assert(section)do { if ((__builtin_expect(!!(!(section)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("section"), "../src/network/networkd-address.c" , 884, __PRETTY_FUNCTION__); } while (0); | |||
885 | assert(lvalue)do { if ((__builtin_expect(!!(!(lvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("lvalue"), "../src/network/networkd-address.c" , 885, __PRETTY_FUNCTION__); } while (0); | |||
886 | assert(rvalue)do { if ((__builtin_expect(!!(!(rvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("rvalue"), "../src/network/networkd-address.c" , 886, __PRETTY_FUNCTION__); } while (0); | |||
887 | assert(data)do { if ((__builtin_expect(!!(!(data)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("data"), "../src/network/networkd-address.c" , 887, __PRETTY_FUNCTION__); } while (0); | |||
888 | ||||
889 | r = address_new_static(network, filename, section_line, &n); | |||
890 | if (r < 0) | |||
891 | return r; | |||
892 | ||||
893 | r = parse_boolean(rvalue); | |||
894 | if (r < 0) { | |||
895 | log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse address flag, ignoring: %s", rvalue)({ int _level = (3), _e = (r); (log_get_max_level_realm(LOG_REALM_SYSTEMD ) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level , filename, line, _e, "../src/network/networkd-address.c", 895 , __func__, "Failed to parse address flag, ignoring: %s", rvalue ) : -abs(_e); }); | |||
896 | return 0; | |||
897 | } | |||
898 | ||||
899 | if (streq(lvalue, "HomeAddress")(strcmp((lvalue),("HomeAddress")) == 0)) | |||
900 | n->home_address = r; | |||
901 | else if (streq(lvalue, "DuplicateAddressDetection")(strcmp((lvalue),("DuplicateAddressDetection")) == 0)) | |||
902 | n->duplicate_address_detection = r; | |||
903 | else if (streq(lvalue, "ManageTemporaryAddress")(strcmp((lvalue),("ManageTemporaryAddress")) == 0)) | |||
904 | n->manage_temporary_address = r; | |||
905 | else if (streq(lvalue, "PrefixRoute")(strcmp((lvalue),("PrefixRoute")) == 0)) | |||
906 | n->prefix_route = r; | |||
907 | else if (streq(lvalue, "AutoJoin")(strcmp((lvalue),("AutoJoin")) == 0)) | |||
908 | n->autojoin = r; | |||
909 | ||||
910 | return 0; | |||
911 | } | |||
912 | ||||
913 | int config_parse_address_scope(const char *unit, | |||
914 | const char *filename, | |||
915 | unsigned line, | |||
916 | const char *section, | |||
917 | unsigned section_line, | |||
918 | const char *lvalue, | |||
919 | int ltype, | |||
920 | const char *rvalue, | |||
921 | void *data, | |||
922 | void *userdata) { | |||
923 | Network *network = userdata; | |||
924 | _cleanup_(address_freep)__attribute__((cleanup(address_freep))) Address *n = NULL((void*)0); | |||
925 | int r; | |||
926 | ||||
927 | assert(filename)do { if ((__builtin_expect(!!(!(filename)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("filename"), "../src/network/networkd-address.c" , 927, __PRETTY_FUNCTION__); } while (0); | |||
928 | assert(section)do { if ((__builtin_expect(!!(!(section)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("section"), "../src/network/networkd-address.c" , 928, __PRETTY_FUNCTION__); } while (0); | |||
929 | assert(lvalue)do { if ((__builtin_expect(!!(!(lvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("lvalue"), "../src/network/networkd-address.c" , 929, __PRETTY_FUNCTION__); } while (0); | |||
930 | assert(rvalue)do { if ((__builtin_expect(!!(!(rvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("rvalue"), "../src/network/networkd-address.c" , 930, __PRETTY_FUNCTION__); } while (0); | |||
931 | assert(data)do { if ((__builtin_expect(!!(!(data)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("data"), "../src/network/networkd-address.c" , 931, __PRETTY_FUNCTION__); } while (0); | |||
932 | ||||
933 | r = address_new_static(network, filename, section_line, &n); | |||
934 | if (r < 0) | |||
935 | return r; | |||
936 | ||||
937 | if (streq(rvalue, "host")(strcmp((rvalue),("host")) == 0)) | |||
938 | n->scope = RT_SCOPE_HOST; | |||
939 | else if (streq(rvalue, "link")(strcmp((rvalue),("link")) == 0)) | |||
940 | n->scope = RT_SCOPE_LINK; | |||
941 | else if (streq(rvalue, "global")(strcmp((rvalue),("global")) == 0)) | |||
942 | n->scope = RT_SCOPE_UNIVERSE; | |||
943 | else { | |||
944 | r = safe_atou8(rvalue , &n->scope); | |||
945 | if (r < 0) { | |||
946 | log_syntax(unit, LOG_ERR, filename, line, r, "Could not parse address scope \"%s\", ignoring assignment: %m", rvalue)({ int _level = (3), _e = (r); (log_get_max_level_realm(LOG_REALM_SYSTEMD ) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level , filename, line, _e, "../src/network/networkd-address.c", 946 , __func__, "Could not parse address scope \"%s\", ignoring assignment: %m" , rvalue) : -abs(_e); }); | |||
947 | return 0; | |||
948 | } | |||
949 | } | |||
950 | ||||
951 | n = NULL((void*)0); | |||
952 | ||||
953 | return 0; | |||
954 | } | |||
955 | ||||
956 | bool_Bool address_is_ready(const Address *a) { | |||
957 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/network/networkd-address.c" , 957, __PRETTY_FUNCTION__); } while (0); | |||
958 | ||||
959 | if (a->family == AF_INET610) | |||
960 | return !(a->flags & IFA_F_TENTATIVE0x40); | |||
961 | else | |||
962 | return !(a->flags & (IFA_F_TENTATIVE0x40 | IFA_F_DEPRECATED0x20)); | |||
963 | } |