File: | build-scan/../src/network/networkd-lldp-tx.c |
Warning: | line 132, column 24 Potential leak of memory pointed to by 'h' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | ||||
34 | static 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 | ||||
40 | static 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 | ||||
55 | static 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); | |||
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); | |||
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); | |||
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); | |||
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); | |||
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); | |||
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); | |||
82 | ||||
83 | machine_id_length = strlen(machine_id); | |||
84 | ifname_length = strlen(ifname); | |||
85 | ||||
86 | if (port_description) | |||
87 | port_description_length = strlen(port_description); | |||
88 | ||||
89 | if (hostname) | |||
90 | hostname_length = strlen(hostname); | |||
91 | ||||
92 | if (pretty_hostname) | |||
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
| |||
109 | l += 2 + port_description_length; | |||
110 | ||||
111 | /* System Name */ | |||
112 | if (hostname
| |||
113 | l += 2 + hostname_length; | |||
114 | ||||
115 | /* System Description */ | |||
116 | if (pretty_hostname
| |||
117 | l += 2 + pretty_hostname_length; | |||
118 | ||||
119 | packet = malloc(l); | |||
120 | if (!packet) | |||
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
| |||
132 | return r; | |||
| ||||
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 | ||||
189 | static 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 | ||||
225 | static 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); | |||
236 | ||||
237 | if (!link->network || link->network->lldp_emit == LLDP_EMIT_NO) | |||
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); | |||
241 | ||||
242 | r = sd_id128_get_machine(&machine_id); | |||
243 | if (r < 0) | |||
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
| |||
253 | SD_LLDP_SYSTEM_CAPABILITIES_ROUTER : | |||
254 | SD_LLDP_SYSTEM_CAPABILITIES_STATION; | |||
255 | ||||
256 | r = lldp_make_packet(link->network->lldp_emit, | |||
257 | &link->mac, | |||
258 | sd_id128_to_string(machine_id, machine_id_string), | |||
259 | link->ifname, | |||
260 | (uint16_t) ttl, | |||
261 | link->network
| |||
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 | ||||
273 | static 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); | |||
| ||||
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); | |||
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..."); }); | |||
282 | ||||
283 | r = link_send_lldp(link); | |||
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(), ¤t) >= 0)do { if ((__builtin_expect(!!(!(sd_event_now(sd_event_source_get_event (s), clock_boottime_or_monotonic(), ¤t) >= 0)),0 ))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("sd_event_now(sd_event_source_get_event(s), clock_boottime_or_monotonic(), ¤t) >= 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 | ||||
306 | int 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 | ||||
354 | void 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 | ||||
360 | int 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 | } |