Bug Summary

File:build-scan/../src/network/netdev/wireguard.c
Warning:line 611, column 24
Potential leak of memory pointed to by 'host'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name wireguard.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -fdenormal-fp-math=preserve-sign,preserve-sign -ffp-contract=fast -fno-rounding-math -ffast-math -ffinite-math-only -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -include config.h -I src/network/libnetworkd-core.a.p -I src/network -I ../src/network -I src/basic -I ../src/basic -I src/shared -I ../src/shared -I src/systemd -I ../src/systemd -I src/journal -I ../src/journal -I src/journal-remote -I ../src/journal-remote -I src/nspawn -I ../src/nspawn -I src/resolve -I ../src/resolve -I src/timesync -I ../src/timesync -I ../src/time-wait-sync -I src/login -I ../src/login -I src/udev -I ../src/udev -I src/libudev -I ../src/libudev -I src/core -I ../src/core -I ../src/libsystemd/sd-bus -I ../src/libsystemd/sd-device -I ../src/libsystemd/sd-hwdb -I ../src/libsystemd/sd-id128 -I ../src/libsystemd/sd-netlink -I ../src/libsystemd/sd-network -I src/libsystemd-network -I ../src/libsystemd-network -I . -I .. -D _FILE_OFFSET_BITS=64 -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wwrite-strings -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Wno-format-signedness -Wno-error=nonnull -std=gnu99 -fconst-strings -fdebug-compilation-dir /home/mrc0mmand/repos/@redhat-plumbers/systemd-rhel8/build-scan -ferror-limit 19 -fvisibility hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -analyzer-output=html -faddrsig -o /tmp/scan-build-2021-07-16-221226-1465241-1 -x c ../src/network/netdev/wireguard.c
1/* SPDX-License-Identifier: LGPL-2.1+ */
2/***
3 Copyright © 2016-2017 Jörg Thalheim <joerg@thalheim.io>
4 Copyright © 2015-2017 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
5***/
6
7#include <sys/ioctl.h>
8#include <net/if.h>
9
10#include "alloc-util.h"
11#include "parse-util.h"
12#include "fd-util.h"
13#include "strv.h"
14#include "hexdecoct.h"
15#include "string-util.h"
16#include "wireguard.h"
17#include "networkd-link.h"
18#include "networkd-util.h"
19#include "networkd-manager.h"
20#include "wireguard-netlink.h"
21
22static void resolve_endpoints(NetDev *netdev);
23
24static WireguardPeer *wireguard_peer_new(Wireguard *w, unsigned section) {
25 WireguardPeer *peer;
26
27 assert(w)do { if ((__builtin_expect(!!(!(w)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("w"), "../src/network/netdev/wireguard.c"
, 27, __PRETTY_FUNCTION__); } while (0)
;
28
29 if (w->last_peer_section == section && w->peers)
30 return w->peers;
31
32 peer = new0(WireguardPeer, 1)((WireguardPeer*) calloc((1), sizeof(WireguardPeer)));
33 if (!peer)
34 return NULL((void*)0);
35 peer->flags = WGPEER_F_REPLACE_ALLOWEDIPS;
36
37 LIST_PREPEND(peers, w->peers, peer)do { typeof(*(w->peers)) **_head = &(w->peers), *_item
= (peer); do { if ((__builtin_expect(!!(!(_item)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("_item"), "../src/network/netdev/wireguard.c"
, 37, __PRETTY_FUNCTION__); } while (0); if ((_item->peers_next
= *_head)) _item->peers_next->peers_prev = _item; _item
->peers_prev = ((void*)0); *_head = _item; } while (0)
;
38 w->last_peer_section = section;
39
40 return peer;
41}
42
43static int set_wireguard_interface(NetDev *netdev) {
44 int r;
45 unsigned int i, j;
46 WireguardPeer *peer, *peer_start;
47 WireguardIPmask *mask, *mask_start = NULL((void*)0);
48 _cleanup_(sd_netlink_message_unrefp)__attribute__((cleanup(sd_netlink_message_unrefp))) sd_netlink_message *message = NULL((void*)0);
49 Wireguard *w;
50 uint32_t serial;
51
52 assert(netdev)do { if ((__builtin_expect(!!(!(netdev)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("netdev"), "../src/network/netdev/wireguard.c"
, 52, __PRETTY_FUNCTION__); } while (0)
;
53 w = WIREGUARD(netdev);
54 assert(w)do { if ((__builtin_expect(!!(!(w)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("w"), "../src/network/netdev/wireguard.c"
, 54, __PRETTY_FUNCTION__); } while (0)
;
55
56 peer_start = w->peers;
57
58 do {
59 message = sd_netlink_message_unref(message);
60
61 r = sd_genl_message_new(netdev->manager->genl, SD_GENL_WIREGUARD, WG_CMD_SET_DEVICE, &message);
62 if (r < 0)
63 return log_netdev_error_errno(netdev, r, "Failed to allocate generic netlink message: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/wireguard.c", 63, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Failed to allocate generic netlink message: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/wireguard.c", 63, __func__, "Failed to allocate generic netlink message: %m"
); })
;
64
65 r = sd_netlink_message_append_string(message, WGDEVICE_A_IFNAME, netdev->ifname);
66 if (r < 0)
67 return log_netdev_error_errno(netdev, r, "Could not append wireguard interface name: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/wireguard.c", 67, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not append wireguard interface name: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/wireguard.c", 67, __func__, "Could not append wireguard interface name: %m"
); })
;
68
69 if (peer_start == w->peers) {
70 r = sd_netlink_message_append_data(message, WGDEVICE_A_PRIVATE_KEY, &w->private_key, WG_KEY_LEN32);
71 if (r < 0)
72 return log_netdev_error_errno(netdev, r, "Could not append wireguard private key: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/wireguard.c", 72, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not append wireguard private key: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/wireguard.c", 72, __func__, "Could not append wireguard private key: %m"
); })
;
73
74 r = sd_netlink_message_append_u16(message, WGDEVICE_A_LISTEN_PORT, w->port);
75 if (r < 0)
76 return log_netdev_error_errno(netdev, r, "Could not append wireguard port: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/wireguard.c", 76, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not append wireguard port: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/wireguard.c", 76, __func__, "Could not append wireguard port: %m"
); })
;
77
78 r = sd_netlink_message_append_u32(message, WGDEVICE_A_FWMARK, w->fwmark);
79 if (r < 0)
80 return log_netdev_error_errno(netdev, r, "Could not append wireguard fwmark: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/wireguard.c", 80, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not append wireguard fwmark: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/wireguard.c", 80, __func__, "Could not append wireguard fwmark: %m"
); })
;
81
82 r = sd_netlink_message_append_u32(message, WGDEVICE_A_FLAGS, w->flags);
83 if (r < 0)
84 return log_netdev_error_errno(netdev, r, "Could not append wireguard flags: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/wireguard.c", 84, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not append wireguard flags: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/wireguard.c", 84, __func__, "Could not append wireguard flags: %m"
); })
;
85 }
86
87 r = sd_netlink_message_open_container(message, WGDEVICE_A_PEERS);
88 if (r < 0)
89 return log_netdev_error_errno(netdev, r, "Could not append wireguard peer attributes: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/wireguard.c", 89, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not append wireguard peer attributes: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/wireguard.c", 89, __func__, "Could not append wireguard peer attributes: %m"
); })
;
90
91 i = 0;
92
93 LIST_FOREACH(peers, peer, peer_start)for ((peer) = (peer_start); (peer); (peer) = (peer)->peers_next
)
{
94 r = sd_netlink_message_open_array(message, ++i);
95 if (r < 0)
96 break;
97
98 r = sd_netlink_message_append_data(message, WGPEER_A_PUBLIC_KEY, &peer->public_key, sizeof(peer->public_key));
99 if (r < 0)
100 break;
101
102 if (!mask_start) {
103 r = sd_netlink_message_append_data(message, WGPEER_A_PRESHARED_KEY, &peer->preshared_key, WG_KEY_LEN32);
104 if (r < 0)
105 break;
106
107 r = sd_netlink_message_append_u32(message, WGPEER_A_FLAGS, peer->flags);
108 if (r < 0)
109 break;
110
111 r = sd_netlink_message_append_u32(message, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL, peer->persistent_keepalive_interval);
112 if (r < 0)
113 break;
114
115 if (peer->endpoint.sa.sa_family == AF_INET2) {
116 r = sd_netlink_message_append_data(message, WGPEER_A_ENDPOINT, &peer->endpoint.in, sizeof(peer->endpoint.in));
117 if (r < 0)
118 break;
119 } else if (peer->endpoint.sa.sa_family == AF_INET610) {
120 r = sd_netlink_message_append_data(message, WGPEER_A_ENDPOINT, &peer->endpoint.in6, sizeof(peer->endpoint.in6));
121 if (r < 0)
122 break;
123 }
124
125 mask_start = peer->ipmasks;
126 }
127
128 r = sd_netlink_message_open_container(message, WGPEER_A_ALLOWEDIPS);
129 if (r < 0) {
130 mask_start = NULL((void*)0);
131 break;
132 }
133 j = 0;
134 LIST_FOREACH(ipmasks, mask, mask_start)for ((mask) = (mask_start); (mask); (mask) = (mask)->ipmasks_next
)
{
135 r = sd_netlink_message_open_array(message, ++j);
136 if (r < 0)
137 break;
138
139 r = sd_netlink_message_append_u16(message, WGALLOWEDIP_A_FAMILY, mask->family);
140 if (r < 0)
141 break;
142
143 if (mask->family == AF_INET2) {
144 r = sd_netlink_message_append_in_addr(message, WGALLOWEDIP_A_IPADDR, &mask->ip.in);
145 if (r < 0)
146 break;
147 } else if (mask->family == AF_INET610) {
148 r = sd_netlink_message_append_in6_addr(message, WGALLOWEDIP_A_IPADDR, &mask->ip.in6);
149 if (r < 0)
150 break;
151 }
152
153 r = sd_netlink_message_append_u8(message, WGALLOWEDIP_A_CIDR_MASK, mask->cidr);
154 if (r < 0)
155 break;
156
157 r = sd_netlink_message_close_container(message);
158 if (r < 0)
159 return log_netdev_error_errno(netdev, r, "Could not add wireguard allowed ip: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/wireguard.c", 159, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not add wireguard allowed ip: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/wireguard.c", 159, __func__, "Could not add wireguard allowed ip: %m"
); })
;
160 }
161 mask_start = mask;
162 if (mask_start) {
163 r = sd_netlink_message_cancel_array(message);
164 if (r < 0)
165 return log_netdev_error_errno(netdev, r, "Could not cancel wireguard allowed ip message attribute: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/wireguard.c", 165, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not cancel wireguard allowed ip message attribute: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/wireguard.c", 165, __func__, "Could not cancel wireguard allowed ip message attribute: %m"
); })
;
166 }
167 r = sd_netlink_message_close_container(message);
168 if (r < 0)
169 return log_netdev_error_errno(netdev, r, "Could not add wireguard allowed ip: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/wireguard.c", 169, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not add wireguard allowed ip: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/wireguard.c", 169, __func__, "Could not add wireguard allowed ip: %m"
); })
;
170
171 r = sd_netlink_message_close_container(message);
172 if (r < 0)
173 return log_netdev_error_errno(netdev, r, "Could not add wireguard peer: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/wireguard.c", 173, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not add wireguard peer: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/wireguard.c", 173, __func__, "Could not add wireguard peer: %m"
); })
;
174 }
175
176 peer_start = peer;
177 if (peer_start && !mask_start) {
178 r = sd_netlink_message_cancel_array(message);
179 if (r < 0)
180 return log_netdev_error_errno(netdev, r, "Could not cancel wireguard peers: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/wireguard.c", 180, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not cancel wireguard peers: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/wireguard.c", 180, __func__, "Could not cancel wireguard peers: %m"
); })
;
181 }
182
183 r = sd_netlink_message_close_container(message);
184 if (r < 0)
185 return log_netdev_error_errno(netdev, r, "Could not close wireguard container: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/wireguard.c", 185, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not close wireguard container: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/wireguard.c", 185, __func__, "Could not close wireguard container: %m"
); })
;
186
187 r = sd_netlink_send(netdev->manager->genl, message, &serial);
188 if (r < 0)
189 return log_netdev_error_errno(netdev, r, "Could not set wireguard device: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/wireguard.c", 189, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not set wireguard device: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/wireguard.c", 189, __func__, "Could not set wireguard device: %m"
); })
;
190
191 } while (peer || mask_start);
192
193 return 0;
194}
195
196static WireguardEndpoint* wireguard_endpoint_free(WireguardEndpoint *e) {
197 if (!e)
198 return NULL((void*)0);
199 netdev_unref(e->netdev);
200 e->host = mfree(e->host);
201 e->port = mfree(e->port);
202 return mfree(e);
203}
204
205DEFINE_TRIVIAL_CLEANUP_FUNC(WireguardEndpoint*, wireguard_endpoint_free)static inline void wireguard_endpoint_freep(WireguardEndpoint
* *p) { if (*p) wireguard_endpoint_free(*p); }
;
206
207static int on_resolve_retry(sd_event_source *s, usec_t usec, void *userdata) {
208 NetDev *netdev = userdata;
209 Wireguard *w;
210
211 assert(netdev)do { if ((__builtin_expect(!!(!(netdev)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("netdev"), "../src/network/netdev/wireguard.c"
, 211, __PRETTY_FUNCTION__); } while (0)
;
212 w = WIREGUARD(netdev);
213 assert(w)do { if ((__builtin_expect(!!(!(w)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("w"), "../src/network/netdev/wireguard.c"
, 213, __PRETTY_FUNCTION__); } while (0)
;
214
215 w->resolve_retry_event_source = sd_event_source_unref(w->resolve_retry_event_source);
216
217 w->unresolved_endpoints = TAKE_PTR(w->failed_endpoints)({ typeof(w->failed_endpoints) _ptr_ = (w->failed_endpoints
); (w->failed_endpoints) = ((void*)0); _ptr_; })
;
218
219 resolve_endpoints(netdev);
220
221 return 0;
222}
223
224/*
225 * Given the number of retries this function will return will an exponential
226 * increasing time in milliseconds to wait starting at 200ms and capped at 25 seconds.
227 */
228static int exponential_backoff_milliseconds(unsigned n_retries) {
229 return (2 << MAX(n_retries, 7U)__extension__ ({ const typeof((n_retries)) __unique_prefix_A12
= ((n_retries)); const typeof((7U)) __unique_prefix_B13 = ((
7U)); __unique_prefix_A12 > __unique_prefix_B13 ? __unique_prefix_A12
: __unique_prefix_B13; })
) * 100 * USEC_PER_MSEC((usec_t) 1000ULL);
230}
231
232static int wireguard_resolve_handler(sd_resolve_query *q,
233 int ret,
234 const struct addrinfo *ai,
235 void *userdata) {
236 NetDev *netdev;
237 Wireguard *w;
238 _cleanup_(wireguard_endpoint_freep)__attribute__((cleanup(wireguard_endpoint_freep))) WireguardEndpoint *e;
239 int r;
240
241 assert(userdata)do { if ((__builtin_expect(!!(!(userdata)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("userdata"), "../src/network/netdev/wireguard.c"
, 241, __PRETTY_FUNCTION__); } while (0)
;
242 e = userdata;
243 netdev = e->netdev;
244
245 assert(netdev)do { if ((__builtin_expect(!!(!(netdev)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("netdev"), "../src/network/netdev/wireguard.c"
, 245, __PRETTY_FUNCTION__); } while (0)
;
246 w = WIREGUARD(netdev);
247 assert(w)do { if ((__builtin_expect(!!(!(w)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("w"), "../src/network/netdev/wireguard.c"
, 247, __PRETTY_FUNCTION__); } while (0)
;
248
249 w->resolve_query = sd_resolve_query_unref(w->resolve_query);
250
251 if (ret != 0) {
252 log_netdev_error(netdev, "Failed to resolve host '%s:%s': %s", e->host, e->port, gai_strerror(ret))({ const NetDev *_n = (netdev); _n ? log_object_internal(3, 0
, "../src/network/netdev/wireguard.c", 252, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Failed to resolve host '%s:%s': %s"
, e->host, e->port, gai_strerror(ret)) : log_internal_realm
(((LOG_REALM_SYSTEMD) << 10 | ((3))), 0, "../src/network/netdev/wireguard.c"
, 252, __func__, "Failed to resolve host '%s:%s': %s", e->
host, e->port, gai_strerror(ret)); })
;
253 LIST_PREPEND(endpoints, w->failed_endpoints, e)do { typeof(*(w->failed_endpoints)) **_head = &(w->
failed_endpoints), *_item = (e); do { if ((__builtin_expect(!
!(!(_item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, (
"_item"), "../src/network/netdev/wireguard.c", 253, __PRETTY_FUNCTION__
); } while (0); if ((_item->endpoints_next = *_head)) _item
->endpoints_next->endpoints_prev = _item; _item->endpoints_prev
= ((void*)0); *_head = _item; } while (0)
;
254 e = NULL((void*)0);
255 } else if ((ai->ai_family == AF_INET2 && ai->ai_addrlen == sizeof(struct sockaddr_in)) ||
256 (ai->ai_family == AF_INET610 && ai->ai_addrlen == sizeof(struct sockaddr_in6)))
257 memcpy(&e->peer->endpoint, ai->ai_addr, ai->ai_addrlen);
258 else
259 log_netdev_error(netdev, "Neither IPv4 nor IPv6 address found for peer endpoint: %s:%s", e->host, e->port)({ const NetDev *_n = (netdev); _n ? log_object_internal(3, 0
, "../src/network/netdev/wireguard.c", 259, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Neither IPv4 nor IPv6 address found for peer endpoint: %s:%s"
, e->host, e->port) : log_internal_realm(((LOG_REALM_SYSTEMD
) << 10 | ((3))), 0, "../src/network/netdev/wireguard.c"
, 259, __func__, "Neither IPv4 nor IPv6 address found for peer endpoint: %s:%s"
, e->host, e->port); })
;
260
261 if (w->unresolved_endpoints) {
262 resolve_endpoints(netdev);
263 return 0;
264 }
265
266 set_wireguard_interface(netdev);
267 if (w->failed_endpoints) {
268 w->n_retries++;
269 r = sd_event_add_time(netdev->manager->event,
270 &w->resolve_retry_event_source,
271 CLOCK_MONOTONIC1,
272 now(CLOCK_MONOTONIC1) + exponential_backoff_milliseconds(w->n_retries),
273 0,
274 on_resolve_retry,
275 netdev);
276 if (r < 0)
277 log_netdev_warning_errno(netdev, r, "Could not arm resolve retry handler: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(4, r
, "../src/network/netdev/wireguard.c", 277, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not arm resolve retry handler: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), r, "../src/network/netdev/wireguard.c", 277, __func__, "Could not arm resolve retry handler: %m"
); })
;
278 }
279
280 return 0;
281}
282
283static void resolve_endpoints(NetDev *netdev) {
284 int r = 0;
285 Wireguard *w;
286 WireguardEndpoint *endpoint;
287 static const struct addrinfo hints = {
288 .ai_family = AF_UNSPEC0,
289 .ai_socktype = SOCK_DGRAMSOCK_DGRAM,
290 .ai_protocol = IPPROTO_UDPIPPROTO_UDP
291 };
292
293 assert(netdev)do { if ((__builtin_expect(!!(!(netdev)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("netdev"), "../src/network/netdev/wireguard.c"
, 293, __PRETTY_FUNCTION__); } while (0)
;
294 w = WIREGUARD(netdev);
295 assert(w)do { if ((__builtin_expect(!!(!(w)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("w"), "../src/network/netdev/wireguard.c"
, 295, __PRETTY_FUNCTION__); } while (0)
;
296
297 LIST_FOREACH(endpoints, endpoint, w->unresolved_endpoints)for ((endpoint) = (w->unresolved_endpoints); (endpoint); (
endpoint) = (endpoint)->endpoints_next)
{
298 r = sd_resolve_getaddrinfo(netdev->manager->resolve,
299 &w->resolve_query,
300 endpoint->host,
301 endpoint->port,
302 &hints,
303 wireguard_resolve_handler,
304 endpoint);
305
306 if (r == -ENOBUFS105)
307 break;
308
309 LIST_REMOVE(endpoints, w->unresolved_endpoints, endpoint)do { typeof(*(w->unresolved_endpoints)) **_head = &(w->
unresolved_endpoints), *_item = (endpoint); do { if ((__builtin_expect
(!!(!(_item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD,
("_item"), "../src/network/netdev/wireguard.c", 309, __PRETTY_FUNCTION__
); } while (0); if (_item->endpoints_next) _item->endpoints_next
->endpoints_prev = _item->endpoints_prev; if (_item->
endpoints_prev) _item->endpoints_prev->endpoints_next =
_item->endpoints_next; else { do { if ((__builtin_expect(
!!(!(*_head == _item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("*_head == _item"), "../src/network/netdev/wireguard.c", 309
, __PRETTY_FUNCTION__); } while (0); *_head = _item->endpoints_next
; } _item->endpoints_next = _item->endpoints_prev = ((void
*)0); } while (0)
;
310
311 if (r < 0)
312 log_netdev_error_errno(netdev, r, "Failed create resolver: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/wireguard.c", 312, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Failed create resolver: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/wireguard.c", 312, __func__, "Failed create resolver: %m"
); })
;
313 }
314}
315
316static int netdev_wireguard_post_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
317 Wireguard *w;
318
319 assert(netdev)do { if ((__builtin_expect(!!(!(netdev)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("netdev"), "../src/network/netdev/wireguard.c"
, 319, __PRETTY_FUNCTION__); } while (0)
;
320 w = WIREGUARD(netdev);
321 assert(w)do { if ((__builtin_expect(!!(!(w)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("w"), "../src/network/netdev/wireguard.c"
, 321, __PRETTY_FUNCTION__); } while (0)
;
322
323 set_wireguard_interface(netdev);
324 resolve_endpoints(netdev);
325 return 0;
326}
327
328int config_parse_wireguard_listen_port(const char *unit,
329 const char *filename,
330 unsigned line,
331 const char *section,
332 unsigned section_line,
333 const char *lvalue,
334 int ltype,
335 const char *rvalue,
336 void *data,
337 void *userdata) {
338 uint16_t *s = data;
339 uint16_t port = 0;
340 int r;
341
342 assert(rvalue)do { if ((__builtin_expect(!!(!(rvalue)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("rvalue"), "../src/network/netdev/wireguard.c"
, 342, __PRETTY_FUNCTION__); } while (0)
;
343 assert(data)do { if ((__builtin_expect(!!(!(data)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("data"), "../src/network/netdev/wireguard.c"
, 343, __PRETTY_FUNCTION__); } while (0)
;
344
345 if (!streq(rvalue, "auto")(strcmp((rvalue),("auto")) == 0)) {
346 r = parse_ip_port(rvalue, &port);
347 if (r < 0)
348 log_syntax(unit, LOG_ERR, filename, line, r, "Invalid port specification, 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/netdev/wireguard.c", 348
, __func__, "Invalid port specification, ignoring assignment: %s"
, rvalue) : -abs(_e); })
;
349 }
350
351 *s = port;
352
353 return 0;
354}
355
356static int parse_wireguard_key(const char *unit,
357 const char *filename,
358 unsigned line,
359 const char *section,
360 unsigned section_line,
361 const char *lvalue,
362 int ltype,
363 const char *rvalue,
364 void *data,
365 void *userdata) {
366 _cleanup_free___attribute__((cleanup(freep))) void *key = NULL((void*)0);
367 size_t len;
368 int r;
369
370 assert(filename)do { if ((__builtin_expect(!!(!(filename)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("filename"), "../src/network/netdev/wireguard.c"
, 370, __PRETTY_FUNCTION__); } while (0)
;
371 assert(rvalue)do { if ((__builtin_expect(!!(!(rvalue)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("rvalue"), "../src/network/netdev/wireguard.c"
, 371, __PRETTY_FUNCTION__); } while (0)
;
372 assert(userdata)do { if ((__builtin_expect(!!(!(userdata)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("userdata"), "../src/network/netdev/wireguard.c"
, 372, __PRETTY_FUNCTION__); } while (0)
;
373
374 r = unbase64mem(rvalue, strlen(rvalue), &key, &len);
375 if (r < 0) {
376 log_syntax(unit, LOG_ERR, filename, line, r, "Could not parse wireguard key \"%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/netdev/wireguard.c", 376
, __func__, "Could not parse wireguard key \"%s\", ignoring assignment: %m"
, rvalue) : -abs(_e); })
;
377 return 0;
378 }
379 if (len != WG_KEY_LEN32) {
380 log_syntax(unit, LOG_ERR, filename, line, EINVAL,({ int _level = (3), _e = (22); (log_get_max_level_realm(LOG_REALM_SYSTEMD
) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level
, filename, line, _e, "../src/network/netdev/wireguard.c", 381
, __func__, "Wireguard key is too short, ignoring assignment: %s"
, rvalue) : -abs(_e); })
381 "Wireguard key is too short, ignoring assignment: %s", rvalue)({ int _level = (3), _e = (22); (log_get_max_level_realm(LOG_REALM_SYSTEMD
) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level
, filename, line, _e, "../src/network/netdev/wireguard.c", 381
, __func__, "Wireguard key is too short, ignoring assignment: %s"
, rvalue) : -abs(_e); })
;
382 return 0;
383 }
384
385 memcpy(userdata, key, WG_KEY_LEN32);
386 return true1;
387}
388
389int config_parse_wireguard_private_key(const char *unit,
390 const char *filename,
391 unsigned line,
392 const char *section,
393 unsigned section_line,
394 const char *lvalue,
395 int ltype,
396 const char *rvalue,
397 void *data,
398 void *userdata) {
399 Wireguard *w;
400
401 assert(data)do { if ((__builtin_expect(!!(!(data)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("data"), "../src/network/netdev/wireguard.c"
, 401, __PRETTY_FUNCTION__); } while (0)
;
402
403 w = WIREGUARD(data);
404
405 assert(w)do { if ((__builtin_expect(!!(!(w)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("w"), "../src/network/netdev/wireguard.c"
, 405, __PRETTY_FUNCTION__); } while (0)
;
406
407 return parse_wireguard_key(unit,
408 filename,
409 line,
410 section,
411 section_line,
412 lvalue,
413 ltype,
414 rvalue,
415 data,
416 &w->private_key);
417
418}
419
420int config_parse_wireguard_preshared_key(const char *unit,
421 const char *filename,
422 unsigned line,
423 const char *section,
424 unsigned section_line,
425 const char *lvalue,
426 int ltype,
427 const char *rvalue,
428 void *data,
429 void *userdata) {
430 Wireguard *w;
431 WireguardPeer *peer;
432
433 assert(data)do { if ((__builtin_expect(!!(!(data)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("data"), "../src/network/netdev/wireguard.c"
, 433, __PRETTY_FUNCTION__); } while (0)
;
434
435 w = WIREGUARD(data);
436
437 assert(w)do { if ((__builtin_expect(!!(!(w)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("w"), "../src/network/netdev/wireguard.c"
, 437, __PRETTY_FUNCTION__); } while (0)
;
438
439 peer = wireguard_peer_new(w, section_line);
440 if (!peer)
441 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/network/netdev/wireguard.c"
, 441, __func__)
;
442
443 return parse_wireguard_key(unit,
444 filename,
445 line,
446 section,
447 section_line,
448 lvalue,
449 ltype,
450 rvalue,
451 data,
452 peer->preshared_key);
453}
454
455int config_parse_wireguard_public_key(const char *unit,
456 const char *filename,
457 unsigned line,
458 const char *section,
459 unsigned section_line,
460 const char *lvalue,
461 int ltype,
462 const char *rvalue,
463 void *data,
464 void *userdata) {
465 Wireguard *w;
466 WireguardPeer *peer;
467
468 assert(data)do { if ((__builtin_expect(!!(!(data)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("data"), "../src/network/netdev/wireguard.c"
, 468, __PRETTY_FUNCTION__); } while (0)
;
469
470 w = WIREGUARD(data);
471
472 assert(w)do { if ((__builtin_expect(!!(!(w)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("w"), "../src/network/netdev/wireguard.c"
, 472, __PRETTY_FUNCTION__); } while (0)
;
473
474 peer = wireguard_peer_new(w, section_line);
475 if (!peer)
476 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/network/netdev/wireguard.c"
, 476, __func__)
;
477
478 return parse_wireguard_key(unit,
479 filename,
480 line,
481 section,
482 section_line,
483 lvalue,
484 ltype,
485 rvalue,
486 data,
487 peer->public_key);
488}
489
490int config_parse_wireguard_allowed_ips(const char *unit,
491 const char *filename,
492 unsigned line,
493 const char *section,
494 unsigned section_line,
495 const char *lvalue,
496 int ltype,
497 const char *rvalue,
498 void *data,
499 void *userdata) {
500 union in_addr_union addr;
501 unsigned char prefixlen;
502 int r, family;
503 Wireguard *w;
504 WireguardPeer *peer;
505 WireguardIPmask *ipmask;
506
507 assert(rvalue)do { if ((__builtin_expect(!!(!(rvalue)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("rvalue"), "../src/network/netdev/wireguard.c"
, 507, __PRETTY_FUNCTION__); } while (0)
;
508 assert(data)do { if ((__builtin_expect(!!(!(data)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("data"), "../src/network/netdev/wireguard.c"
, 508, __PRETTY_FUNCTION__); } while (0)
;
509
510 w = WIREGUARD(data);
511
512 peer = wireguard_peer_new(w, section_line);
513 if (!peer)
514 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/network/netdev/wireguard.c"
, 514, __func__)
;
515
516 for (;;) {
517 _cleanup_free___attribute__((cleanup(freep))) char *word = NULL((void*)0);
518
519 r = extract_first_word(&rvalue, &word, "," WHITESPACE" \t\n\r", 0);
520 if (r == 0)
521 break;
522 if (r == -ENOMEM12)
523 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/network/netdev/wireguard.c"
, 523, __func__)
;
524 if (r < 0) {
525 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to split allowed ips \"%s\" option: %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/netdev/wireguard.c", 525
, __func__, "Failed to split allowed ips \"%s\" option: %m", rvalue
) : -abs(_e); })
;
526 break;
527 }
528
529 r = in_addr_prefix_from_string_auto(word, &family, &addr, &prefixlen);
530 if (r < 0) {
531 log_syntax(unit, LOG_ERR, filename, line, r, "Network address is invalid, ignoring assignment: %s", word)({ 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/netdev/wireguard.c", 531
, __func__, "Network address is invalid, ignoring assignment: %s"
, word) : -abs(_e); })
;
532 return 0;
533 }
534
535 ipmask = new0(WireguardIPmask, 1)((WireguardIPmask*) calloc((1), sizeof(WireguardIPmask)));
536 if (!ipmask)
537 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/network/netdev/wireguard.c"
, 537, __func__)
;
538 ipmask->family = family;
539 ipmask->ip.in6 = addr.in6;
540 ipmask->cidr = prefixlen;
541
542 LIST_PREPEND(ipmasks, peer->ipmasks, ipmask)do { typeof(*(peer->ipmasks)) **_head = &(peer->ipmasks
), *_item = (ipmask); do { if ((__builtin_expect(!!(!(_item))
,0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("_item"), "../src/network/netdev/wireguard.c"
, 542, __PRETTY_FUNCTION__); } while (0); if ((_item->ipmasks_next
= *_head)) _item->ipmasks_next->ipmasks_prev = _item; _item
->ipmasks_prev = ((void*)0); *_head = _item; } while (0)
;
543 }
544
545 return 0;
546}
547
548int config_parse_wireguard_endpoint(const char *unit,
549 const char *filename,
550 unsigned line,
551 const char *section,
552 unsigned section_line,
553 const char *lvalue,
554 int ltype,
555 const char *rvalue,
556 void *data,
557 void *userdata) {
558 Wireguard *w;
559 WireguardPeer *peer;
560 size_t len;
561 const char *begin, *end = NULL((void*)0);
562 _cleanup_free___attribute__((cleanup(freep))) char *host = NULL((void*)0), *port = NULL((void*)0);
563 _cleanup_(wireguard_endpoint_freep)__attribute__((cleanup(wireguard_endpoint_freep))) WireguardEndpoint *endpoint = NULL((void*)0);
564
565 assert(data)do { if ((__builtin_expect(!!(!(data)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("data"), "../src/network/netdev/wireguard.c"
, 565, __PRETTY_FUNCTION__); } while (0)
;
1
Assuming 'data' is non-null
2
Taking false branch
3
Loop condition is false. Exiting loop
566 assert(rvalue)do { if ((__builtin_expect(!!(!(rvalue)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("rvalue"), "../src/network/netdev/wireguard.c"
, 566, __PRETTY_FUNCTION__); } while (0)
;
4
Assuming 'rvalue' is non-null
5
Taking false branch
6
Loop condition is false. Exiting loop
567
568 w = WIREGUARD(data);
569
570 assert(w)do { if ((__builtin_expect(!!(!(w)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("w"), "../src/network/netdev/wireguard.c"
, 570, __PRETTY_FUNCTION__); } while (0)
;
7
Taking false branch
8
Loop condition is false. Exiting loop
571
572 peer = wireguard_peer_new(w, section_line);
573 if (!peer
8.1
'peer' is non-null
)
9
Taking false branch
574 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/network/netdev/wireguard.c"
, 574, __func__)
;
575
576 endpoint = new0(WireguardEndpoint, 1)((WireguardEndpoint*) calloc((1), sizeof(WireguardEndpoint)));
577 if (!endpoint)
10
Assuming 'endpoint' is non-null
11
Taking false branch
578 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/network/netdev/wireguard.c"
, 578, __func__)
;
579
580 if (rvalue[0] == '[') {
12
Assuming the condition is false
13
Taking false branch
581 begin = &rvalue[1];
582 end = strchr(rvalue, ']');
583 if (!end) {
584 log_syntax(unit, LOG_ERR, filename, line, 0, "Unable to find matching brace of endpoint, 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/netdev/wireguard.c", 584
, __func__, "Unable to find matching brace of endpoint, ignoring assignment: %s"
, rvalue) : -abs(_e); })
;
585 return 0;
586 }
587 len = end - begin;
588 ++end;
589 if (*end != ':' || !*(end + 1)) {
590 log_syntax(unit, LOG_ERR, filename, line, 0, "Unable to find port of endpoint: %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/netdev/wireguard.c", 590
, __func__, "Unable to find port of endpoint: %s", rvalue) : -
abs(_e); })
;
591 return 0;
592 }
593 ++end;
594 } else {
595 begin = rvalue;
596 end = strrchr(rvalue, ':');
597 if (!end || !*(end + 1)) {
14
Assuming 'end' is non-null
15
Assuming the condition is false
16
Taking false branch
598 log_syntax(unit, LOG_ERR, filename, line, 0, "Unable to find port of endpoint: %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/netdev/wireguard.c", 598
, __func__, "Unable to find port of endpoint: %s", rvalue) : -
abs(_e); })
;
599 return 0;
600 }
601 len = end - begin;
602 ++end;
603 }
604
605 host = strndup(begin, len);
17
Memory is allocated
606 if (!host)
18
Assuming 'host' is non-null
19
Taking false branch
607 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/network/netdev/wireguard.c"
, 607, __func__)
;
608
609 port = strdup(end);
610 if (!port)
20
Assuming 'port' is null
21
Taking true branch
611 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/network/netdev/wireguard.c"
, 611, __func__)
;
22
Potential leak of memory pointed to by 'host'
612
613 endpoint->peer = TAKE_PTR(peer)({ typeof(peer) _ptr_ = (peer); (peer) = ((void*)0); _ptr_; }
)
;
614 endpoint->host = TAKE_PTR(host)({ typeof(host) _ptr_ = (host); (host) = ((void*)0); _ptr_; }
)
;
615 endpoint->port = TAKE_PTR(port)({ typeof(port) _ptr_ = (port); (port) = ((void*)0); _ptr_; }
)
;
616 endpoint->netdev = netdev_ref(data);
617 LIST_PREPEND(endpoints, w->unresolved_endpoints, endpoint)do { typeof(*(w->unresolved_endpoints)) **_head = &(w->
unresolved_endpoints), *_item = (endpoint); do { if ((__builtin_expect
(!!(!(_item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD,
("_item"), "../src/network/netdev/wireguard.c", 617, __PRETTY_FUNCTION__
); } while (0); if ((_item->endpoints_next = *_head)) _item
->endpoints_next->endpoints_prev = _item; _item->endpoints_prev
= ((void*)0); *_head = _item; } while (0)
;
618 endpoint = NULL((void*)0);
619
620 return 0;
621}
622
623int config_parse_wireguard_keepalive(const char *unit,
624 const char *filename,
625 unsigned line,
626 const char *section,
627 unsigned section_line,
628 const char *lvalue,
629 int ltype,
630 const char *rvalue,
631 void *data,
632 void *userdata) {
633 int r;
634 uint16_t keepalive = 0;
635 Wireguard *w;
636 WireguardPeer *peer;
637
638 assert(rvalue)do { if ((__builtin_expect(!!(!(rvalue)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("rvalue"), "../src/network/netdev/wireguard.c"
, 638, __PRETTY_FUNCTION__); } while (0)
;
639 assert(data)do { if ((__builtin_expect(!!(!(data)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("data"), "../src/network/netdev/wireguard.c"
, 639, __PRETTY_FUNCTION__); } while (0)
;
640
641 w = WIREGUARD(data);
642
643 assert(w)do { if ((__builtin_expect(!!(!(w)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("w"), "../src/network/netdev/wireguard.c"
, 643, __PRETTY_FUNCTION__); } while (0)
;
644
645 peer = wireguard_peer_new(w, section_line);
646 if (!peer)
647 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/network/netdev/wireguard.c"
, 647, __func__)
;
648
649 if (streq(rvalue, "off")(strcmp((rvalue),("off")) == 0))
650 keepalive = 0;
651 else {
652 r = safe_atou16(rvalue, &keepalive);
653 if (r < 0)
654 log_syntax(unit, LOG_ERR, filename, line, r, "The persistent keepalive interval must be 0-65535. Ignore 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/netdev/wireguard.c", 654
, __func__, "The persistent keepalive interval must be 0-65535. Ignore assignment: %s"
, rvalue) : -abs(_e); })
;
655 }
656
657 peer->persistent_keepalive_interval = keepalive;
658 return 0;
659}
660
661static void wireguard_init(NetDev *netdev) {
662 Wireguard *w;
663
664 assert(netdev)do { if ((__builtin_expect(!!(!(netdev)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("netdev"), "../src/network/netdev/wireguard.c"
, 664, __PRETTY_FUNCTION__); } while (0)
;
665
666 w = WIREGUARD(netdev);
667
668 assert(w)do { if ((__builtin_expect(!!(!(w)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("w"), "../src/network/netdev/wireguard.c"
, 668, __PRETTY_FUNCTION__); } while (0)
;
669
670 w->flags = WGDEVICE_F_REPLACE_PEERS;
671}
672
673static void wireguard_done(NetDev *netdev) {
674 Wireguard *w;
675 WireguardPeer *peer;
676 WireguardIPmask *mask;
677
678 assert(netdev)do { if ((__builtin_expect(!!(!(netdev)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("netdev"), "../src/network/netdev/wireguard.c"
, 678, __PRETTY_FUNCTION__); } while (0)
;
679 w = WIREGUARD(netdev);
680 assert(!w->unresolved_endpoints)do { if ((__builtin_expect(!!(!(!w->unresolved_endpoints))
,0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("!w->unresolved_endpoints"
), "../src/network/netdev/wireguard.c", 680, __PRETTY_FUNCTION__
); } while (0)
;
681 w->resolve_retry_event_source = sd_event_source_unref(w->resolve_retry_event_source);
682
683 while ((peer = w->peers)) {
684 LIST_REMOVE(peers, w->peers, peer)do { typeof(*(w->peers)) **_head = &(w->peers), *_item
= (peer); do { if ((__builtin_expect(!!(!(_item)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("_item"), "../src/network/netdev/wireguard.c"
, 684, __PRETTY_FUNCTION__); } while (0); if (_item->peers_next
) _item->peers_next->peers_prev = _item->peers_prev;
if (_item->peers_prev) _item->peers_prev->peers_next
= _item->peers_next; else { do { if ((__builtin_expect(!!
(!(*_head == _item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("*_head == _item"), "../src/network/netdev/wireguard.c", 684
, __PRETTY_FUNCTION__); } while (0); *_head = _item->peers_next
; } _item->peers_next = _item->peers_prev = ((void*)0);
} while (0)
;
685 while ((mask = peer->ipmasks)) {
686 LIST_REMOVE(ipmasks, peer->ipmasks, mask)do { typeof(*(peer->ipmasks)) **_head = &(peer->ipmasks
), *_item = (mask); do { if ((__builtin_expect(!!(!(_item)),0
))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("_item"), "../src/network/netdev/wireguard.c"
, 686, __PRETTY_FUNCTION__); } while (0); if (_item->ipmasks_next
) _item->ipmasks_next->ipmasks_prev = _item->ipmasks_prev
; if (_item->ipmasks_prev) _item->ipmasks_prev->ipmasks_next
= _item->ipmasks_next; else { do { if ((__builtin_expect(
!!(!(*_head == _item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("*_head == _item"), "../src/network/netdev/wireguard.c", 686
, __PRETTY_FUNCTION__); } while (0); *_head = _item->ipmasks_next
; } _item->ipmasks_next = _item->ipmasks_prev = ((void*
)0); } while (0)
;
687 free(mask);
688 }
689 free(peer);
690 }
691}
692
693const NetDevVTable wireguard_vtable = {
694 .object_size = sizeof(Wireguard),
695 .sections = "Match\0NetDev\0WireGuard\0WireGuardPeer\0",
696 .post_create = netdev_wireguard_post_create,
697 .init = wireguard_init,
698 .done = wireguard_done,
699 .create_type = NETDEV_CREATE_INDEPENDENT,
700};