1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2016 Lennart Poettering
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
25 #include "alloc-util.h"
28 #include "hostname-util.h"
29 #include "networkd-lldp-tx.h"
30 #include "networkd-manager.h"
31 #include "parse-util.h"
32 #include "random-util.h"
33 #include "socket-util.h"
34 #include "string-util.h"
35 #include "unaligned.h"
37 /* The LLDP spec calls this "txFastInit", see 9.2.5.19 */
38 #define LLDP_TX_FAST_INIT 4U
40 /* The LLDP spec calls this "msgTxHold", see 9.2.5.6 */
41 #define LLDP_TX_HOLD 4U
43 /* The jitter range to add, see 9.2.2. */
44 #define LLDP_JITTER_USEC (400U * USEC_PER_MSEC)
46 /* The LLDP spec calls this msgTxInterval, but we subtract half the jitter off it. */
47 #define LLDP_TX_INTERVAL_USEC (30U * USEC_PER_SEC - LLDP_JITTER_USEC / 2)
49 /* The LLDP spec calls this msgFastTx, but we subtract half the jitter off it. */
50 #define LLDP_FAST_TX_USEC (1U * USEC_PER_SEC - LLDP_JITTER_USEC / 2)
52 static const struct ether_addr lldp_multicast_addr
[_LLDP_EMIT_MAX
] = {
53 [LLDP_EMIT_NEAREST_BRIDGE
] = {{ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e }},
54 [LLDP_EMIT_NON_TPMR_BRIDGE
] = {{ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 }},
55 [LLDP_EMIT_CUSTOMER_BRIDGE
] = {{ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }},
58 static int lldp_write_tlv_header(uint8_t **p
, uint8_t id
, size_t sz
) {
66 (*p
)[0] = (id
<< 1) | !!(sz
& 256);
73 static int lldp_make_packet(
75 const struct ether_addr
*hwaddr
,
76 const char *machine_id
,
79 const char *port_description
,
81 const char *pretty_hostname
,
82 uint16_t system_capabilities
,
83 uint16_t enabled_capabilities
,
84 void **ret
, size_t *sz
) {
86 size_t machine_id_length
, ifname_length
, port_description_length
= 0, hostname_length
= 0, pretty_hostname_length
= 0;
87 _cleanup_free_
void *packet
= NULL
;
88 struct ether_header
*h
;
93 assert(mode
> LLDP_EMIT_NO
);
94 assert(mode
< _LLDP_EMIT_MAX
);
101 machine_id_length
= strlen(machine_id
);
102 ifname_length
= strlen(ifname
);
104 if (port_description
)
105 port_description_length
= strlen(port_description
);
108 hostname_length
= strlen(hostname
);
111 pretty_hostname_length
= strlen(pretty_hostname
);
113 l
= sizeof(struct ether_header
) +
115 2 + 1 + machine_id_length
+
117 2 + 1 + ifname_length
+
120 /* System Capabilities */
125 /* Port Description */
126 if (port_description
)
127 l
+= 2 + port_description_length
;
131 l
+= 2 + hostname_length
;
133 /* System Description */
135 l
+= 2 + pretty_hostname_length
;
141 h
= (struct ether_header
*) packet
;
142 h
->ether_type
= htobe16(ETHERTYPE_LLDP
);
143 memcpy(h
->ether_dhost
, lldp_multicast_addr
+ mode
, ETH_ALEN
);
144 memcpy(h
->ether_shost
, hwaddr
, ETH_ALEN
);
146 p
= (uint8_t*) packet
+ sizeof(struct ether_header
);
148 r
= lldp_write_tlv_header(&p
, SD_LLDP_TYPE_CHASSIS_ID
, 1 + machine_id_length
);
151 *(p
++) = SD_LLDP_CHASSIS_SUBTYPE_LOCALLY_ASSIGNED
;
152 p
= mempcpy(p
, machine_id
, machine_id_length
);
154 r
= lldp_write_tlv_header(&p
, SD_LLDP_TYPE_PORT_ID
, 1 + ifname_length
);
157 *(p
++) = SD_LLDP_PORT_SUBTYPE_INTERFACE_NAME
;
158 p
= mempcpy(p
, ifname
, ifname_length
);
160 r
= lldp_write_tlv_header(&p
, SD_LLDP_TYPE_TTL
, 2);
163 unaligned_write_be16(p
, ttl
);
166 if (port_description
) {
167 r
= lldp_write_tlv_header(&p
, SD_LLDP_TYPE_PORT_DESCRIPTION
, port_description_length
);
170 p
= mempcpy(p
, port_description
, port_description_length
);
174 r
= lldp_write_tlv_header(&p
, SD_LLDP_TYPE_SYSTEM_NAME
, hostname_length
);
177 p
= mempcpy(p
, hostname
, hostname_length
);
180 if (pretty_hostname
) {
181 r
= lldp_write_tlv_header(&p
, SD_LLDP_TYPE_SYSTEM_DESCRIPTION
, pretty_hostname_length
);
184 p
= mempcpy(p
, pretty_hostname
, pretty_hostname_length
);
187 r
= lldp_write_tlv_header(&p
, SD_LLDP_TYPE_SYSTEM_CAPABILITIES
, 4);
190 unaligned_write_be16(p
, system_capabilities
);
192 unaligned_write_be16(p
, enabled_capabilities
);
195 r
= lldp_write_tlv_header(&p
, SD_LLDP_TYPE_END
, 0);
199 assert(p
== (uint8_t*) packet
+ l
);
208 static int lldp_send_packet(
210 const struct ether_addr
*address
,
212 size_t packet_size
) {
214 union sockaddr_union sa
= {
215 .ll
.sll_family
= AF_PACKET
,
216 .ll
.sll_protocol
= htobe16(ETHERTYPE_LLDP
),
217 .ll
.sll_ifindex
= ifindex
,
218 .ll
.sll_halen
= ETH_ALEN
,
221 _cleanup_close_
int fd
= -1;
226 assert(packet
|| packet_size
<= 0);
228 memcpy(sa
.ll
.sll_addr
, address
, ETH_ALEN
);
230 fd
= socket(PF_PACKET
, SOCK_RAW
|SOCK_CLOEXEC
, IPPROTO_RAW
);
234 l
= sendto(fd
, packet
, packet_size
, MSG_NOSIGNAL
, &sa
.sa
, sizeof(sa
.ll
));
238 if ((size_t) l
!= packet_size
)
244 static int link_send_lldp(Link
*link
) {
245 char machine_id_string
[SD_ID128_STRING_MAX
];
246 _cleanup_free_
char *hostname
= NULL
, *pretty_hostname
= NULL
;
247 _cleanup_free_
void *packet
= NULL
;
248 size_t packet_size
= 0;
249 sd_id128_t machine_id
;
256 if (!link
->network
|| link
->network
->lldp_emit
== LLDP_EMIT_NO
)
259 assert(link
->network
->lldp_emit
< _LLDP_EMIT_MAX
);
261 r
= sd_id128_get_machine(&machine_id
);
265 (void) gethostname_strict(&hostname
);
266 (void) parse_env_file("/etc/machine-info", NEWLINE
, "PRETTY_HOSTNAME", &pretty_hostname
, NULL
);
268 assert_cc(LLDP_TX_INTERVAL_USEC
* LLDP_TX_HOLD
+ 1 <= (UINT16_MAX
- 1) * USEC_PER_SEC
);
269 ttl
= DIV_ROUND_UP(LLDP_TX_INTERVAL_USEC
* LLDP_TX_HOLD
+ 1, USEC_PER_SEC
);
271 caps
= (link
->network
&& link
->network
->ip_forward
!= ADDRESS_FAMILY_NO
) ?
272 SD_LLDP_SYSTEM_CAPABILITIES_ROUTER
:
273 SD_LLDP_SYSTEM_CAPABILITIES_STATION
;
275 r
= lldp_make_packet(link
->network
->lldp_emit
,
277 sd_id128_to_string(machine_id
, machine_id_string
),
280 link
->network
? link
->network
->description
: NULL
,
283 SD_LLDP_SYSTEM_CAPABILITIES_STATION
|SD_LLDP_SYSTEM_CAPABILITIES_BRIDGE
|SD_LLDP_SYSTEM_CAPABILITIES_ROUTER
,
285 &packet
, &packet_size
);
289 return lldp_send_packet(link
->ifindex
, lldp_multicast_addr
+ link
->network
->lldp_emit
, packet
, packet_size
);
292 static int on_lldp_timer(sd_event_source
*s
, usec_t t
, void *userdata
) {
293 Link
*link
= userdata
;
294 usec_t current
, delay
, next
;
300 log_link_debug(link
, "Sending LLDP packet...");
302 r
= link_send_lldp(link
);
304 log_link_debug_errno(link
, r
, "Failed to send LLDP packet, ignoring: %m");
306 if (link
->lldp_tx_fast
> 0)
307 link
->lldp_tx_fast
--;
309 assert_se(sd_event_now(sd_event_source_get_event(s
), clock_boottime_or_monotonic(), ¤t
) >= 0);
311 delay
= link
->lldp_tx_fast
> 0 ? LLDP_FAST_TX_USEC
: LLDP_TX_INTERVAL_USEC
;
312 next
= usec_add(usec_add(current
, delay
), (usec_t
) random_u64() % LLDP_JITTER_USEC
);
314 r
= sd_event_source_set_time(s
, next
);
316 return log_link_error_errno(link
, r
, "Failed to restart LLDP timer: %m");
318 r
= sd_event_source_set_enabled(s
, SD_EVENT_ONESHOT
);
320 return log_link_error_errno(link
, r
, "Failed to enable LLDP timer: %m");
325 int link_lldp_emit_start(Link
*link
) {
331 if (!link
->network
|| link
->network
->lldp_emit
== LLDP_EMIT_NO
) {
332 link_lldp_emit_stop(link
);
336 /* Starts the LLDP transmission in "fast" mode. If it is already started, turns "fast" mode back on again. */
338 link
->lldp_tx_fast
= LLDP_TX_FAST_INIT
;
340 next
= usec_add(usec_add(now(clock_boottime_or_monotonic()), LLDP_FAST_TX_USEC
),
341 (usec_t
) random_u64() % LLDP_JITTER_USEC
);
343 if (link
->lldp_emit_event_source
) {
346 /* Lower the timeout, maybe */
347 r
= sd_event_source_get_time(link
->lldp_emit_event_source
, &old
);
354 return sd_event_source_set_time(link
->lldp_emit_event_source
, next
);
356 r
= sd_event_add_time(
357 link
->manager
->event
,
358 &link
->lldp_emit_event_source
,
359 clock_boottime_or_monotonic(),
367 (void) sd_event_source_set_description(link
->lldp_emit_event_source
, "lldp-tx");
373 void link_lldp_emit_stop(Link
*link
) {
376 link
->lldp_emit_event_source
= sd_event_source_unref(link
->lldp_emit_event_source
);
379 int config_parse_lldp_emit(
381 const char *filename
,
384 unsigned section_line
,
391 LLDPEmit
*emit
= data
;
399 *emit
= LLDP_EMIT_NO
;
400 else if (streq(rvalue
, "nearest-bridge"))
401 *emit
= LLDP_EMIT_NEAREST_BRIDGE
;
402 else if (streq(rvalue
, "non-tpmr-bridge"))
403 *emit
= LLDP_EMIT_NON_TPMR_BRIDGE
;
404 else if (streq(rvalue
, "customer-bridge"))
405 *emit
= LLDP_EMIT_CUSTOMER_BRIDGE
;
407 r
= parse_boolean(rvalue
);
409 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Failed to parse LLDP emission setting, ignoring: %s", rvalue
);
413 *emit
= r
? LLDP_EMIT_NEAREST_BRIDGE
: LLDP_EMIT_NO
;