Bug Summary

File:build-scan/../src/network/networkd-lldp-tx.c
Warning:line 132, column 24
Potential leak of memory pointed to by 'h'

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 networkd-lldp-tx.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/networkd-lldp-tx.c
1/* SPDX-License-Identifier: LGPL-2.1+ */
2
3#include <endian.h>
4#include <inttypes.h>
5#include <string.h>
6
7#include "alloc-util.h"
8#include "fd-util.h"
9#include "fileio.h"
10#include "hostname-util.h"
11#include "networkd-lldp-tx.h"
12#include "networkd-manager.h"
13#include "parse-util.h"
14#include "random-util.h"
15#include "socket-util.h"
16#include "string-util.h"
17#include "unaligned.h"
18
19/* The LLDP spec calls this "txFastInit", see 9.2.5.19 */
20#define LLDP_TX_FAST_INIT4U 4U
21
22/* The LLDP spec calls this "msgTxHold", see 9.2.5.6 */
23#define LLDP_TX_HOLD4U 4U
24
25/* The jitter range to add, see 9.2.2. */
26#define LLDP_JITTER_USEC(400U * ((usec_t) 1000ULL)) (400U * USEC_PER_MSEC((usec_t) 1000ULL))
27
28/* The LLDP spec calls this msgTxInterval, but we subtract half the jitter off it. */
29#define LLDP_TX_INTERVAL_USEC(30U * ((usec_t) 1000000ULL) - (400U * ((usec_t) 1000ULL)) / 2
)
(30U * USEC_PER_SEC((usec_t) 1000000ULL) - LLDP_JITTER_USEC(400U * ((usec_t) 1000ULL)) / 2)
30
31/* The LLDP spec calls this msgFastTx, but we subtract half the jitter off it. */
32#define LLDP_FAST_TX_USEC(1U * ((usec_t) 1000000ULL) - (400U * ((usec_t) 1000ULL)) / 2
)
(1U * USEC_PER_SEC((usec_t) 1000000ULL) - LLDP_JITTER_USEC(400U * ((usec_t) 1000ULL)) / 2)
33
34static const struct ether_addr lldp_multicast_addr[_LLDP_EMIT_MAX] = {
35 [LLDP_EMIT_NEAREST_BRIDGE] = {{ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e }},
36 [LLDP_EMIT_NON_TPMR_BRIDGE] = {{ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 }},
37 [LLDP_EMIT_CUSTOMER_BRIDGE] = {{ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }},
38};
39
40static int lldp_write_tlv_header(uint8_t **p, uint8_t id, size_t sz) {
41 assert(p)do { if ((__builtin_expect(!!(!(p)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("p"), "../src/network/networkd-lldp-tx.c"
, 41, __PRETTY_FUNCTION__); } while (0)
;
42
43 if (id > 127)
44 return -EBADMSG74;
45 if (sz > 511)
46 return -ENOBUFS105;
47
48 (*p)[0] = (id << 1) | !!(sz & 256);
49 (*p)[1] = sz & 255;
50
51 *p = *p + 2;
52 return 0;
53}
54
55static int lldp_make_packet(
56 LLDPEmit mode,
57 const struct ether_addr *hwaddr,
58 const char *machine_id,
59 const char *ifname,
60 uint16_t ttl,
61 const char *port_description,
62 const char *hostname,
63 const char *pretty_hostname,
64 uint16_t system_capabilities,
65 uint16_t enabled_capabilities,
66 void **ret, size_t *sz) {
67
68 size_t machine_id_length, ifname_length, port_description_length = 0, hostname_length = 0, pretty_hostname_length = 0;
69 _cleanup_free___attribute__((cleanup(freep))) void *packet = NULL((void*)0);
70 struct ether_header *h;
71 uint8_t *p;
72 size_t l;
73 int r;
74
75 assert(mode > LLDP_EMIT_NO)do { if ((__builtin_expect(!!(!(mode > LLDP_EMIT_NO)),0)))
log_assert_failed_realm(LOG_REALM_SYSTEMD, ("mode > LLDP_EMIT_NO"
), "../src/network/networkd-lldp-tx.c", 75, __PRETTY_FUNCTION__
); } while (0)
;
23
Taking false branch
24
Loop condition is false. Exiting loop
76 assert(mode < _LLDP_EMIT_MAX)do { if ((__builtin_expect(!!(!(mode < _LLDP_EMIT_MAX)),0)
)) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("mode < _LLDP_EMIT_MAX"
), "../src/network/networkd-lldp-tx.c", 76, __PRETTY_FUNCTION__
); } while (0)
;
25
Taking false branch
26
Loop condition is false. Exiting loop
77 assert(hwaddr)do { if ((__builtin_expect(!!(!(hwaddr)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("hwaddr"), "../src/network/networkd-lldp-tx.c"
, 77, __PRETTY_FUNCTION__); } while (0)
;
27
Taking false branch
28
Loop condition is false. Exiting loop
78 assert(machine_id)do { if ((__builtin_expect(!!(!(machine_id)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("machine_id"), "../src/network/networkd-lldp-tx.c"
, 78, __PRETTY_FUNCTION__); } while (0)
;
29
Assuming 'machine_id' is non-null
30
Taking false branch
31
Loop condition is false. Exiting loop
79 assert(ifname)do { if ((__builtin_expect(!!(!(ifname)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ifname"), "../src/network/networkd-lldp-tx.c"
, 79, __PRETTY_FUNCTION__); } while (0)
;
32
Assuming 'ifname' is non-null
33
Taking false branch
34
Loop condition is false. Exiting loop
80 assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/network/networkd-lldp-tx.c"
, 80, __PRETTY_FUNCTION__); } while (0)
;
35
Taking false branch
36
Loop condition is false. Exiting loop
81 assert(sz)do { if ((__builtin_expect(!!(!(sz)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("sz"), "../src/network/networkd-lldp-tx.c"
, 81, __PRETTY_FUNCTION__); } while (0)
;
37
Taking false branch
38
Loop condition is false. Exiting loop
82
83 machine_id_length = strlen(machine_id);
84 ifname_length = strlen(ifname);
85
86 if (port_description)
39
Assuming 'port_description' is null
40
Taking false branch
87 port_description_length = strlen(port_description);
88
89 if (hostname)
41
Assuming 'hostname' is null
42
Taking false branch
90 hostname_length = strlen(hostname);
91
92 if (pretty_hostname)
43
Assuming 'pretty_hostname' is null
44
Taking false branch
93 pretty_hostname_length = strlen(pretty_hostname);
94
95 l = sizeof(struct ether_header) +
96 /* Chassis ID */
97 2 + 1 + machine_id_length +
98 /* Port ID */
99 2 + 1 + ifname_length +
100 /* TTL */
101 2 + 2 +
102 /* System Capabilities */
103 2 + 4 +
104 /* End */
105 2;
106
107 /* Port Description */
108 if (port_description
44.1
'port_description' is null
)
45
Taking false branch
109 l += 2 + port_description_length;
110
111 /* System Name */
112 if (hostname
45.1
'hostname' is null
)
46
Taking false branch
113 l += 2 + hostname_length;
114
115 /* System Description */
116 if (pretty_hostname
46.1
'pretty_hostname' is null
)
47
Taking false branch
117 l += 2 + pretty_hostname_length;
118
119 packet = malloc(l);
48
Memory is allocated
120 if (!packet)
49
Assuming 'packet' is non-null
50
Taking false branch
121 return -ENOMEM12;
122
123 h = (struct ether_header*) packet;
124 h->ether_type = htobe16(ETHERTYPE_LLDP0x88cc);
125 memcpy(h->ether_dhost, lldp_multicast_addr + mode, ETH_ALEN6);
126 memcpy(h->ether_shost, hwaddr, ETH_ALEN6);
127
128 p = (uint8_t*) packet + sizeof(struct ether_header);
129
130 r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_CHASSIS_ID, 1 + machine_id_length);
131 if (r
50.1
'r' is < 0
< 0)
51
Taking true branch
132 return r;
52
Potential leak of memory pointed to by 'h'
133 *(p++) = SD_LLDP_CHASSIS_SUBTYPE_LOCALLY_ASSIGNED;
134 p = mempcpy(p, machine_id, machine_id_length);
135
136 r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_PORT_ID, 1 + ifname_length);
137 if (r < 0)
138 return r;
139 *(p++) = SD_LLDP_PORT_SUBTYPE_INTERFACE_NAME;
140 p = mempcpy(p, ifname, ifname_length);
141
142 r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_TTL, 2);
143 if (r < 0)
144 return r;
145 unaligned_write_be16(p, ttl);
146 p += 2;
147
148 if (port_description) {
149 r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_PORT_DESCRIPTION, port_description_length);
150 if (r < 0)
151 return r;
152 p = mempcpy(p, port_description, port_description_length);
153 }
154
155 if (hostname) {
156 r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_SYSTEM_NAME, hostname_length);
157 if (r < 0)
158 return r;
159 p = mempcpy(p, hostname, hostname_length);
160 }
161
162 if (pretty_hostname) {
163 r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_SYSTEM_DESCRIPTION, pretty_hostname_length);
164 if (r < 0)
165 return r;
166 p = mempcpy(p, pretty_hostname, pretty_hostname_length);
167 }
168
169 r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_SYSTEM_CAPABILITIES, 4);
170 if (r < 0)
171 return r;
172 unaligned_write_be16(p, system_capabilities);
173 p += 2;
174 unaligned_write_be16(p, enabled_capabilities);
175 p += 2;
176
177 r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_END, 0);
178 if (r < 0)
179 return r;
180
181 assert(p == (uint8_t*) packet + l)do { if ((__builtin_expect(!!(!(p == (uint8_t*) packet + l)),
0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("p == (uint8_t*) packet + l"
), "../src/network/networkd-lldp-tx.c", 181, __PRETTY_FUNCTION__
); } while (0)
;
182
183 *ret = TAKE_PTR(packet)({ typeof(packet) _ptr_ = (packet); (packet) = ((void*)0); _ptr_
; })
;
184 *sz = l;
185
186 return 0;
187}
188
189static int lldp_send_packet(
190 int ifindex,
191 const struct ether_addr *address,
192 const void *packet,
193 size_t packet_size) {
194
195 union sockaddr_union sa = {
196 .ll.sll_family = AF_PACKET17,
197 .ll.sll_protocol = htobe16(ETHERTYPE_LLDP0x88cc),
198 .ll.sll_ifindex = ifindex,
199 .ll.sll_halen = ETH_ALEN6,
200 };
201
202 _cleanup_close___attribute__((cleanup(closep))) int fd = -1;
203 ssize_t l;
204
205 assert(ifindex > 0)do { if ((__builtin_expect(!!(!(ifindex > 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ifindex > 0"), "../src/network/networkd-lldp-tx.c"
, 205, __PRETTY_FUNCTION__); } while (0)
;
206 assert(address)do { if ((__builtin_expect(!!(!(address)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("address"), "../src/network/networkd-lldp-tx.c"
, 206, __PRETTY_FUNCTION__); } while (0)
;
207 assert(packet || packet_size <= 0)do { if ((__builtin_expect(!!(!(packet || packet_size <= 0
)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("packet || packet_size <= 0"
), "../src/network/networkd-lldp-tx.c", 207, __PRETTY_FUNCTION__
); } while (0)
;
208
209 memcpy(sa.ll.sll_addr, address, ETH_ALEN6);
210
211 fd = socket(PF_PACKET17, SOCK_RAWSOCK_RAW|SOCK_CLOEXECSOCK_CLOEXEC, IPPROTO_RAWIPPROTO_RAW);
212 if (fd < 0)
213 return -errno(*__errno_location ());
214
215 l = sendto(fd, packet, packet_size, MSG_NOSIGNALMSG_NOSIGNAL, &sa.sa, sizeof(sa.ll));
216 if (l < 0)
217 return -errno(*__errno_location ());
218
219 if ((size_t) l != packet_size)
220 return -EIO5;
221
222 return 0;
223}
224
225static int link_send_lldp(Link *link) {
226 char machine_id_string[SD_ID128_STRING_MAX33];
227 _cleanup_free___attribute__((cleanup(freep))) char *hostname = NULL((void*)0), *pretty_hostname = NULL((void*)0);
228 _cleanup_free___attribute__((cleanup(freep))) void *packet = NULL((void*)0);
229 size_t packet_size = 0;
230 sd_id128_t machine_id;
231 uint16_t caps;
232 usec_t ttl;
233 int r;
234
235 assert(link)do { if ((__builtin_expect(!!(!(link)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("link"), "../src/network/networkd-lldp-tx.c"
, 235, __PRETTY_FUNCTION__); } while (0)
;
9
Taking false branch
10
Loop condition is false. Exiting loop
236
237 if (!link->network || link->network->lldp_emit == LLDP_EMIT_NO)
11
Assuming field 'network' is non-null
12
Assuming field 'lldp_emit' is not equal to LLDP_EMIT_NO
13
Taking false branch
238 return 0;
239
240 assert(link->network->lldp_emit < _LLDP_EMIT_MAX)do { if ((__builtin_expect(!!(!(link->network->lldp_emit
< _LLDP_EMIT_MAX)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("link->network->lldp_emit < _LLDP_EMIT_MAX"), "../src/network/networkd-lldp-tx.c"
, 240, __PRETTY_FUNCTION__); } while (0)
;
14
Assuming field 'lldp_emit' is < _LLDP_EMIT_MAX
15
Taking false branch
16
Loop condition is false. Exiting loop
241
242 r = sd_id128_get_machine(&machine_id);
243 if (r < 0)
17
Assuming 'r' is >= 0
18
Taking false branch
244 return r;
245
246 (void) gethostname_strict(&hostname);
247 (void) parse_env_file(NULL((void*)0), "/etc/machine-info", NEWLINE"\n\r", "PRETTY_HOSTNAME", &pretty_hostname, NULL((void*)0));
248
249 assert_cc(LLDP_TX_INTERVAL_USEC * LLDP_TX_HOLD + 1 <= (UINT16_MAX - 1) * USEC_PER_SEC)GCC diagnostic push ; GCC diagnostic ignored "-Wdeclaration-after-statement"
; struct _assert_struct_11 { char x[((30U * ((usec_t) 1000000ULL
) - (400U * ((usec_t) 1000ULL)) / 2) * 4U + 1 <= ((65535) -
1) * ((usec_t) 1000000ULL)) ? 0 : -1]; }; GCC diagnostic pop
;
250 ttl = DIV_ROUND_UP(LLDP_TX_INTERVAL_USEC * LLDP_TX_HOLD + 1, USEC_PER_SEC)({ const typeof(((30U * ((usec_t) 1000000ULL) - (400U * ((usec_t
) 1000ULL)) / 2) * 4U + 1)) __unique_prefix_X12 = (((30U * ((
usec_t) 1000000ULL) - (400U * ((usec_t) 1000ULL)) / 2) * 4U +
1)); const typeof((((usec_t) 1000000ULL))) __unique_prefix_Y13
= ((((usec_t) 1000000ULL))); (__unique_prefix_X12 / __unique_prefix_Y13
+ !!(__unique_prefix_X12 % __unique_prefix_Y13)); })
;
251
252 caps = (link->network
18.1
Field 'network' is non-null
&& link->network->ip_forward != ADDRESS_FAMILY_NO) ?
19
Assuming field 'ip_forward' is equal to ADDRESS_FAMILY_NO
20
'?' condition is false
253 SD_LLDP_SYSTEM_CAPABILITIES_ROUTER :
254 SD_LLDP_SYSTEM_CAPABILITIES_STATION;
255
256 r = lldp_make_packet(link->network->lldp_emit,
22
Calling 'lldp_make_packet'
257 &link->mac,
258 sd_id128_to_string(machine_id, machine_id_string),
259 link->ifname,
260 (uint16_t) ttl,
261 link->network
20.1
Field 'network' is non-null
? link->network->description : NULL((void*)0),
21
'?' condition is true
262 hostname,
263 pretty_hostname,
264 SD_LLDP_SYSTEM_CAPABILITIES_STATION|SD_LLDP_SYSTEM_CAPABILITIES_BRIDGE|SD_LLDP_SYSTEM_CAPABILITIES_ROUTER,
265 caps,
266 &packet, &packet_size);
267 if (r < 0)
268 return r;
269
270 return lldp_send_packet(link->ifindex, lldp_multicast_addr + link->network->lldp_emit, packet, packet_size);
271}
272
273static int on_lldp_timer(sd_event_source *s, usec_t t, void *userdata) {
274 Link *link = userdata;
275 usec_t current, delay, next;
276 int r;
277
278 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/network/networkd-lldp-tx.c"
, 278, __PRETTY_FUNCTION__); } while (0)
;
1
Assuming 's' is non-null
2
Taking false branch
3
Loop condition is false. Exiting loop
279 assert(userdata)do { if ((__builtin_expect(!!(!(userdata)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("userdata"), "../src/network/networkd-lldp-tx.c"
, 279, __PRETTY_FUNCTION__); } while (0)
;
4
Assuming 'userdata' is non-null
5
Taking false branch
6
Loop condition is false. Exiting loop
280
281 log_link_debug(link, "Sending LLDP packet...")({ const Link *_l = (link); _l ? log_object_internal(7, 0, "../src/network/networkd-lldp-tx.c"
, 281, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "Sending LLDP packet...") : log_internal_realm(((LOG_REALM_SYSTEMD
) << 10 | ((7))), 0, "../src/network/networkd-lldp-tx.c"
, 281, __func__, "Sending LLDP packet..."); })
;
7
'?' condition is true
282
283 r = link_send_lldp(link);
8
Calling 'link_send_lldp'
284 if (r < 0)
285 log_link_debug_errno(link, r, "Failed to send LLDP packet, ignoring: %m")({ const Link *_l = (link); _l ? log_object_internal(7, r, "../src/network/networkd-lldp-tx.c"
, 285, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "Failed to send LLDP packet, ignoring: %m") : log_internal_realm
(((LOG_REALM_SYSTEMD) << 10 | ((7))), r, "../src/network/networkd-lldp-tx.c"
, 285, __func__, "Failed to send LLDP packet, ignoring: %m");
})
;
286
287 if (link->lldp_tx_fast > 0)
288 link->lldp_tx_fast--;
289
290 assert_se(sd_event_now(sd_event_source_get_event(s), clock_boottime_or_monotonic(), &current) >= 0)do { if ((__builtin_expect(!!(!(sd_event_now(sd_event_source_get_event
(s), clock_boottime_or_monotonic(), &current) >= 0)),0
))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("sd_event_now(sd_event_source_get_event(s), clock_boottime_or_monotonic(), &current) >= 0"
), "../src/network/networkd-lldp-tx.c", 290, __PRETTY_FUNCTION__
); } while (0)
;
291
292 delay = link->lldp_tx_fast > 0 ? LLDP_FAST_TX_USEC(1U * ((usec_t) 1000000ULL) - (400U * ((usec_t) 1000ULL)) / 2
)
: LLDP_TX_INTERVAL_USEC(30U * ((usec_t) 1000000ULL) - (400U * ((usec_t) 1000ULL)) / 2
)
;
293 next = usec_add(usec_add(current, delay), (usec_t) random_u64() % LLDP_JITTER_USEC(400U * ((usec_t) 1000ULL)));
294
295 r = sd_event_source_set_time(s, next);
296 if (r < 0)
297 return log_link_error_errno(link, r, "Failed to restart LLDP timer: %m")({ const Link *_l = (link); _l ? log_object_internal(3, r, "../src/network/networkd-lldp-tx.c"
, 297, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "Failed to restart LLDP timer: %m") : log_internal_realm
(((LOG_REALM_SYSTEMD) << 10 | ((3))), r, "../src/network/networkd-lldp-tx.c"
, 297, __func__, "Failed to restart LLDP timer: %m"); })
;
298
299 r = sd_event_source_set_enabled(s, SD_EVENT_ONESHOT);
300 if (r < 0)
301 return log_link_error_errno(link, r, "Failed to enable LLDP timer: %m")({ const Link *_l = (link); _l ? log_object_internal(3, r, "../src/network/networkd-lldp-tx.c"
, 301, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "Failed to enable LLDP timer: %m") : log_internal_realm
(((LOG_REALM_SYSTEMD) << 10 | ((3))), r, "../src/network/networkd-lldp-tx.c"
, 301, __func__, "Failed to enable LLDP timer: %m"); })
;
302
303 return 0;
304}
305
306int link_lldp_emit_start(Link *link) {
307 usec_t next;
308 int r;
309
310 assert(link)do { if ((__builtin_expect(!!(!(link)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("link"), "../src/network/networkd-lldp-tx.c"
, 310, __PRETTY_FUNCTION__); } while (0)
;
311
312 if (!link->network || link->network->lldp_emit == LLDP_EMIT_NO) {
313 link_lldp_emit_stop(link);
314 return 0;
315 }
316
317 /* Starts the LLDP transmission in "fast" mode. If it is already started, turns "fast" mode back on again. */
318
319 link->lldp_tx_fast = LLDP_TX_FAST_INIT4U;
320
321 next = usec_add(usec_add(now(clock_boottime_or_monotonic()), LLDP_FAST_TX_USEC(1U * ((usec_t) 1000000ULL) - (400U * ((usec_t) 1000ULL)) / 2
)
),
322 (usec_t) random_u64() % LLDP_JITTER_USEC(400U * ((usec_t) 1000ULL)));
323
324 if (link->lldp_emit_event_source) {
325 usec_t old;
326
327 /* Lower the timeout, maybe */
328 r = sd_event_source_get_time(link->lldp_emit_event_source, &old);
329 if (r < 0)
330 return r;
331
332 if (old <= next)
333 return 0;
334
335 return sd_event_source_set_time(link->lldp_emit_event_source, next);
336 } else {
337 r = sd_event_add_time(
338 link->manager->event,
339 &link->lldp_emit_event_source,
340 clock_boottime_or_monotonic(),
341 next,
342 0,
343 on_lldp_timer,
344 link);
345 if (r < 0)
346 return r;
347
348 (void) sd_event_source_set_description(link->lldp_emit_event_source, "lldp-tx");
349 }
350
351 return 0;
352}
353
354void link_lldp_emit_stop(Link *link) {
355 assert(link)do { if ((__builtin_expect(!!(!(link)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("link"), "../src/network/networkd-lldp-tx.c"
, 355, __PRETTY_FUNCTION__); } while (0)
;
356
357 link->lldp_emit_event_source = sd_event_source_unref(link->lldp_emit_event_source);
358}
359
360int config_parse_lldp_emit(
361 const char *unit,
362 const char *filename,
363 unsigned line,
364 const char *section,
365 unsigned section_line,
366 const char *lvalue,
367 int ltype,
368 const char *rvalue,
369 void *data,
370 void *userdata) {
371
372 LLDPEmit *emit = data;
373 int r;
374
375 assert(filename)do { if ((__builtin_expect(!!(!(filename)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("filename"), "../src/network/networkd-lldp-tx.c"
, 375, __PRETTY_FUNCTION__); } while (0)
;
376 assert(lvalue)do { if ((__builtin_expect(!!(!(lvalue)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("lvalue"), "../src/network/networkd-lldp-tx.c"
, 376, __PRETTY_FUNCTION__); } while (0)
;
377 assert(rvalue)do { if ((__builtin_expect(!!(!(rvalue)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("rvalue"), "../src/network/networkd-lldp-tx.c"
, 377, __PRETTY_FUNCTION__); } while (0)
;
378
379 if (isempty(rvalue))
380 *emit = LLDP_EMIT_NO;
381 else if (streq(rvalue, "nearest-bridge")(strcmp((rvalue),("nearest-bridge")) == 0))
382 *emit = LLDP_EMIT_NEAREST_BRIDGE;
383 else if (streq(rvalue, "non-tpmr-bridge")(strcmp((rvalue),("non-tpmr-bridge")) == 0))
384 *emit = LLDP_EMIT_NON_TPMR_BRIDGE;
385 else if (streq(rvalue, "customer-bridge")(strcmp((rvalue),("customer-bridge")) == 0))
386 *emit = LLDP_EMIT_CUSTOMER_BRIDGE;
387 else {
388 r = parse_boolean(rvalue);
389 if (r < 0) {
390 log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse LLDP emission setting, ignoring: %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-lldp-tx.c", 390
, __func__, "Failed to parse LLDP emission setting, ignoring: %s"
, rvalue) : -abs(_e); })
;
391 return 0;
392 }
393
394 *emit = r ? LLDP_EMIT_NEAREST_BRIDGE : LLDP_EMIT_NO;
395 }
396
397 return 0;
398}