]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/network/networkd-lldp-tx.c
Merge pull request #31455 from keszybz/restore-docs-urls
[thirdparty/systemd.git] / src / network / networkd-lldp-tx.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <net/if.h>
4 #include <net/if_arp.h>
5
6 #include "sd-lldp-tx.h"
7
8 #include "networkd-link.h"
9 #include "networkd-lldp-tx.h"
10 #include "networkd-manager.h"
11 #include "networkd-sysctl.h"
12 #include "parse-util.h"
13 #include "string-table.h"
14 #include "string-util.h"
15 #include "strv.h"
16
17 static bool link_lldp_tx_enabled(Link *link) {
18 assert(link);
19
20 if (link->flags & IFF_LOOPBACK)
21 return false;
22
23 if (link->iftype != ARPHRD_ETHER)
24 return false;
25
26 if (!link->network)
27 return false;
28
29 if (link->kind && STR_IN_SET(link->kind, "bridge", "bond"))
30 return false;
31
32 return link->network->lldp_multicast_mode >= 0 &&
33 link->network->lldp_multicast_mode < _SD_LLDP_MULTICAST_MODE_MAX;
34 }
35
36 int link_lldp_tx_configure(Link *link) {
37 int r;
38
39 assert(link);
40
41 if (!link_lldp_tx_enabled(link))
42 return 0;
43
44 if (link->lldp_tx)
45 return -EBUSY;
46
47 r = sd_lldp_tx_new(&link->lldp_tx);
48 if (r < 0)
49 return r;
50
51 r = sd_lldp_tx_attach_event(link->lldp_tx, link->manager->event, 0);
52 if (r < 0)
53 return r;
54
55 r = sd_lldp_tx_set_ifindex(link->lldp_tx, link->ifindex);
56 if (r < 0)
57 return r;
58
59 r = sd_lldp_tx_set_hwaddr(link->lldp_tx, &link->hw_addr.ether);
60 if (r < 0)
61 return r;
62
63 assert(link->network);
64
65 r = sd_lldp_tx_set_multicast_mode(link->lldp_tx, link->network->lldp_multicast_mode);
66 if (r < 0)
67 return r;
68
69 r = sd_lldp_tx_set_capabilities(link->lldp_tx,
70 SD_LLDP_SYSTEM_CAPABILITIES_STATION |
71 SD_LLDP_SYSTEM_CAPABILITIES_BRIDGE |
72 SD_LLDP_SYSTEM_CAPABILITIES_ROUTER,
73 (link_get_ip_forwarding(link, AF_INET) > 0 || link_get_ip_forwarding(link, AF_INET6) > 0) ?
74 SD_LLDP_SYSTEM_CAPABILITIES_ROUTER : SD_LLDP_SYSTEM_CAPABILITIES_STATION);
75 if (r < 0)
76 return r;
77
78 r = sd_lldp_tx_set_port_description(link->lldp_tx, link->network->description);
79 if (r < 0)
80 return r;
81
82 r = sd_lldp_tx_set_mud_url(link->lldp_tx, link->network->lldp_mudurl);
83 if (r < 0)
84 return r;
85
86 return 0;
87 }
88
89 static const char * const lldp_multicast_mode_table[_SD_LLDP_MULTICAST_MODE_MAX] = {
90 [SD_LLDP_MULTICAST_MODE_NEAREST_BRIDGE] = "nearest-bridge",
91 [SD_LLDP_MULTICAST_MODE_NON_TPMR_BRIDGE] = "non-tpmr-bridge",
92 [SD_LLDP_MULTICAST_MODE_CUSTOMER_BRIDGE] = "customer-bridge",
93 };
94
95 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(lldp_multicast_mode, sd_lldp_multicast_mode_t);
96
97 int config_parse_lldp_multicast_mode(
98 const char *unit,
99 const char *filename,
100 unsigned line,
101 const char *section,
102 unsigned section_line,
103 const char *lvalue,
104 int ltype,
105 const char *rvalue,
106 void *data,
107 void *userdata) {
108
109 sd_lldp_multicast_mode_t m, *mode = ASSERT_PTR(data);
110 int r;
111
112 assert(filename);
113 assert(section);
114 assert(lvalue);
115 assert(rvalue);
116
117 if (isempty(rvalue)) {
118 *mode = _SD_LLDP_MULTICAST_MODE_INVALID;
119 return 0;
120 }
121
122 r = parse_boolean(rvalue);
123 if (r >= 0) {
124 *mode = r == 0 ? _SD_LLDP_MULTICAST_MODE_INVALID : SD_LLDP_MULTICAST_MODE_NEAREST_BRIDGE;
125 return 0;
126 }
127
128 m = lldp_multicast_mode_from_string(rvalue);
129 if (m < 0) {
130 log_syntax(unit, LOG_WARNING, filename, line, m,
131 "Failed to parse %s=, ignoring assignment: %s", lvalue, rvalue);
132 return 0;
133 }
134
135 *mode = m;
136 return 0;
137 }