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