1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
4 #include <net/if_arp.h>
10 #include "networkd-link.h"
11 #include "networkd-lldp-rx.h"
12 #include "networkd-lldp-tx.h"
13 #include "networkd-manager.h"
14 #include "networkd-network.h"
15 #include "string-table.h"
16 #include "string-util.h"
18 #include "tmpfile-util.h"
20 DEFINE_CONFIG_PARSE_ENUM(config_parse_lldp_mode
, lldp_mode
, LLDPMode
, "Failed to parse LLDP= setting.");
22 static const char* const lldp_mode_table
[_LLDP_MODE_MAX
] = {
23 [LLDP_MODE_NO
] = "no",
24 [LLDP_MODE_YES
] = "yes",
25 [LLDP_MODE_ROUTERS_ONLY
] = "routers-only",
28 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(lldp_mode
, LLDPMode
, LLDP_MODE_YES
);
30 static bool link_lldp_rx_enabled(Link
*link
) {
33 if (link
->flags
& IFF_LOOPBACK
)
36 if (link
->iftype
!= ARPHRD_ETHER
)
42 /* LLDP should be handled on bridge and bond slaves as those have a direct connection to their peers,
43 * not on the bridge/bond master. Linux doesn't even (by default) forward lldp packets to the bridge
45 if (link
->kind
&& STR_IN_SET(link
->kind
, "bridge", "bond"))
48 return link
->network
->lldp_mode
!= LLDP_MODE_NO
;
51 static void lldp_rx_handler(sd_lldp_rx
*lldp_rx
, sd_lldp_rx_event_t event
, sd_lldp_neighbor
*n
, void *userdata
) {
52 Link
*link
= ASSERT_PTR(userdata
);
55 if (link
->lldp_tx
&& event
== SD_LLDP_RX_EVENT_ADDED
) {
56 /* If we received information about a new neighbor, restart the LLDP "fast" logic */
58 log_link_debug(link
, "Received LLDP datagram from previously unknown neighbor, restarting 'fast' LLDP transmission.");
60 (void) sd_lldp_tx_stop(link
->lldp_tx
);
61 r
= sd_lldp_tx_start(link
->lldp_tx
);
63 log_link_warning_errno(link
, r
, "Failed to restart LLDP transmission: %m");
67 int link_lldp_rx_configure(Link
*link
) {
70 if (!link_lldp_rx_enabled(link
))
76 r
= sd_lldp_rx_new(&link
->lldp_rx
);
80 r
= sd_lldp_rx_attach_event(link
->lldp_rx
, link
->manager
->event
, 0);
84 r
= sd_lldp_rx_set_ifindex(link
->lldp_rx
, link
->ifindex
);
88 r
= sd_lldp_rx_match_capabilities(link
->lldp_rx
,
89 link
->network
->lldp_mode
== LLDP_MODE_ROUTERS_ONLY
?
90 SD_LLDP_SYSTEM_CAPABILITIES_ALL_ROUTERS
:
91 SD_LLDP_SYSTEM_CAPABILITIES_ALL
);
95 r
= sd_lldp_rx_set_filter_address(link
->lldp_rx
, &link
->hw_addr
.ether
);
99 r
= sd_lldp_rx_set_callback(link
->lldp_rx
, lldp_rx_handler
, link
);