Line data Source code
1 1 : /** @file
2 : @brief LLDP definitions and handler
3 :
4 : This is not to be included by the application.
5 : */
6 :
7 : /*
8 : * Copyright (c) 2017 Intel Corporation
9 : *
10 : * SPDX-License-Identifier: Apache-2.0
11 : */
12 :
13 : #ifndef ZEPHYR_INCLUDE_NET_LLDP_H_
14 : #define ZEPHYR_INCLUDE_NET_LLDP_H_
15 :
16 : /**
17 : * @brief LLDP definitions and helpers
18 : * @defgroup lldp Link Layer Discovery Protocol definitions and helpers
19 : * @since 1.13
20 : * @version 0.8.0
21 : * @ingroup networking
22 : * @{
23 : */
24 :
25 : #ifdef __cplusplus
26 : extern "C" {
27 : #endif
28 :
29 : /** @cond INTERNAL_HIDDEN */
30 :
31 : #define LLDP_TLV_GET_LENGTH(type_length) (type_length & BIT_MASK(9))
32 : #define LLDP_TLV_GET_TYPE(type_length) ((uint8_t)(type_length >> 9))
33 :
34 : /* LLDP Definitions */
35 :
36 : /* According to the spec, End of LLDPDU TLV value is constant. */
37 : #define NET_LLDP_END_LLDPDU_VALUE 0x0000
38 :
39 : /*
40 : * For the Chassis ID TLV Value, if subtype is a MAC address then we must
41 : * use values from CONFIG_NET_LLDP_CHASSIS_ID_MAC0 through
42 : * CONFIG_NET_LLDP_CHASSIS_ID_MAC5. If not, we use CONFIG_NET_LLDP_CHASSIS_ID.
43 : *
44 : * FIXME: implement a similar scheme for subtype 5 (network address).
45 : */
46 : #if defined(CONFIG_NET_LLDP_CHASSIS_ID_SUBTYPE)
47 : #if (CONFIG_NET_LLDP_CHASSIS_ID_SUBTYPE == 4)
48 : #define NET_LLDP_CHASSIS_ID_VALUE \
49 : { \
50 : CONFIG_NET_LLDP_CHASSIS_ID_MAC0, \
51 : CONFIG_NET_LLDP_CHASSIS_ID_MAC1, \
52 : CONFIG_NET_LLDP_CHASSIS_ID_MAC2, \
53 : CONFIG_NET_LLDP_CHASSIS_ID_MAC3, \
54 : CONFIG_NET_LLDP_CHASSIS_ID_MAC4, \
55 : CONFIG_NET_LLDP_CHASSIS_ID_MAC5 \
56 : }
57 :
58 : #define NET_LLDP_CHASSIS_ID_VALUE_LEN (6)
59 : #else
60 : #define NET_LLDP_CHASSIS_ID_VALUE CONFIG_NET_LLDP_CHASSIS_ID
61 : #define NET_LLDP_CHASSIS_ID_VALUE_LEN (sizeof(CONFIG_NET_LLDP_CHASSIS_ID) - 1)
62 : #endif
63 : #else
64 : #define NET_LLDP_CHASSIS_ID_VALUE 0
65 : #define NET_LLDP_CHASSIS_ID_VALUE_LEN 0
66 : #endif
67 :
68 : /*
69 : * For the Port ID TLV Value, if subtype is a MAC address then we must
70 : * use values from CONFIG_NET_LLDP_PORT_ID_MAC0 through
71 : * CONFIG_NET_LLDP_PORT_ID_MAC5. If not, we use CONFIG_NET_LLDP_PORT_ID.
72 : *
73 : * FIXME: implement a similar scheme for subtype 4 (network address).
74 : */
75 : #if defined(CONFIG_NET_LLDP_PORT_ID_SUBTYPE)
76 : #if (CONFIG_NET_LLDP_PORT_ID_SUBTYPE == 3)
77 : #define NET_LLDP_PORT_ID_VALUE \
78 : { \
79 : CONFIG_NET_LLDP_PORT_ID_MAC0, \
80 : CONFIG_NET_LLDP_PORT_ID_MAC1, \
81 : CONFIG_NET_LLDP_PORT_ID_MAC2, \
82 : CONFIG_NET_LLDP_PORT_ID_MAC3, \
83 : CONFIG_NET_LLDP_PORT_ID_MAC4, \
84 : CONFIG_NET_LLDP_PORT_ID_MAC5 \
85 : }
86 :
87 : #define NET_LLDP_PORT_ID_VALUE_LEN (6)
88 : #else
89 : #define NET_LLDP_PORT_ID_VALUE CONFIG_NET_LLDP_PORT_ID
90 : #define NET_LLDP_PORT_ID_VALUE_LEN (sizeof(CONFIG_NET_LLDP_PORT_ID) - 1)
91 : #endif
92 : #else
93 : #define NET_LLDP_PORT_ID_VALUE 0
94 : #define NET_LLDP_PORT_ID_VALUE_LEN 0
95 : #endif
96 :
97 : /*
98 : * TLVs Length.
99 : * Note that TLVs that have a subtype must have a byte added to their length.
100 : */
101 : #define NET_LLDP_CHASSIS_ID_TLV_LEN (NET_LLDP_CHASSIS_ID_VALUE_LEN + 1)
102 : #define NET_LLDP_PORT_ID_TLV_LEN (NET_LLDP_PORT_ID_VALUE_LEN + 1)
103 : #define NET_LLDP_TTL_TLV_LEN (2)
104 :
105 : /*
106 : * Time to Live value.
107 : * Calculate based on section 9.2.5.22 from LLDP spec.
108 : *
109 : * FIXME: when the network interface is about to be ‘disabled’ TTL shall be set
110 : * to zero so LLDP Rx agents can invalidate the entry related to this node.
111 : */
112 : #if defined(CONFIG_NET_LLDP_TX_INTERVAL) && defined(CONFIG_NET_LLDP_TX_HOLD)
113 : #define NET_LLDP_TTL \
114 : MIN((CONFIG_NET_LLDP_TX_INTERVAL * CONFIG_NET_LLDP_TX_HOLD) + 1, 65535)
115 : #endif
116 :
117 :
118 : struct net_if;
119 :
120 : /** @endcond */
121 :
122 : /** TLV Types. Please refer to table 8-1 from IEEE 802.1AB standard. */
123 1 : enum net_lldp_tlv_type {
124 : LLDP_TLV_END_LLDPDU = 0, /**< End Of LLDPDU (optional) */
125 : LLDP_TLV_CHASSIS_ID = 1, /**< Chassis ID (mandatory) */
126 : LLDP_TLV_PORT_ID = 2, /**< Port ID (mandatory) */
127 : LLDP_TLV_TTL = 3, /**< Time To Live (mandatory) */
128 : LLDP_TLV_PORT_DESC = 4, /**< Port Description (optional) */
129 : LLDP_TLV_SYSTEM_NAME = 5, /**< System Name (optional) */
130 : LLDP_TLV_SYSTEM_DESC = 6, /**< System Description (optional) */
131 : LLDP_TLV_SYSTEM_CAPABILITIES = 7, /**< System Capability (optional) */
132 : LLDP_TLV_MANAGEMENT_ADDR = 8, /**< Management Address (optional) */
133 : /* Types 9 - 126 are reserved. */
134 : LLDP_TLV_ORG_SPECIFIC = 127, /**< Org specific TLVs (optional) */
135 : };
136 :
137 : /** Chassis ID TLV, see chapter 8.5.2 in IEEE 802.1AB */
138 1 : struct net_lldp_chassis_tlv {
139 : /** 7 bits for type, 9 bits for length */
140 1 : uint16_t type_length;
141 : /** ID subtype */
142 1 : uint8_t subtype;
143 : /** Chassis ID value */
144 1 : uint8_t value[NET_LLDP_CHASSIS_ID_VALUE_LEN];
145 : } __packed;
146 :
147 : /** Port ID TLV, see chapter 8.5.3 in IEEE 802.1AB */
148 1 : struct net_lldp_port_tlv {
149 : /** 7 bits for type, 9 bits for length */
150 1 : uint16_t type_length;
151 : /** ID subtype */
152 1 : uint8_t subtype;
153 : /** Port ID value */
154 1 : uint8_t value[NET_LLDP_PORT_ID_VALUE_LEN];
155 : } __packed;
156 :
157 : /** Time To Live TLV, see chapter 8.5.4 in IEEE 802.1AB */
158 1 : struct net_lldp_time_to_live_tlv {
159 : /** 7 bits for type, 9 bits for length */
160 1 : uint16_t type_length;
161 : /** Time To Live (TTL) value */
162 1 : uint16_t ttl;
163 : } __packed;
164 :
165 : /**
166 : * LLDP Data Unit (LLDPDU) shall contain the following ordered TLVs
167 : * as stated in "8.2 LLDPDU format" from the IEEE 802.1AB
168 : */
169 1 : struct net_lldpdu {
170 1 : struct net_lldp_chassis_tlv chassis_id; /**< Mandatory Chassis TLV */
171 1 : struct net_lldp_port_tlv port_id; /**< Mandatory Port TLV */
172 1 : struct net_lldp_time_to_live_tlv ttl; /**< Mandatory TTL TLV */
173 : } __packed;
174 :
175 : /**
176 : * @brief Set the LLDP data unit for a network interface.
177 : *
178 : * @param iface Network interface
179 : * @param lldpdu LLDP data unit struct
180 : *
181 : * @return 0 if ok, <0 if error
182 : */
183 1 : int net_lldp_config(struct net_if *iface, const struct net_lldpdu *lldpdu);
184 :
185 : /**
186 : * @brief Set the Optional LLDP TLVs for a network interface.
187 : *
188 : * @param iface Network interface
189 : * @param tlv LLDP optional TLVs following mandatory part
190 : * @param len Length of the optional TLVs
191 : *
192 : * @return 0 if ok, <0 if error
193 : */
194 1 : int net_lldp_config_optional(struct net_if *iface, const uint8_t *tlv,
195 : size_t len);
196 :
197 : /**
198 : * @brief Initialize LLDP engine.
199 : */
200 1 : void net_lldp_init(void);
201 :
202 : /**
203 : * @brief LLDP Receive packet callback
204 : *
205 : * Callback gets called upon receiving packet. It is responsible for
206 : * freeing packet or indicating to the stack that it needs to free packet
207 : * by returning correct net_verdict.
208 : *
209 : * Returns:
210 : * - NET_DROP, if packet was invalid, rejected or we want the stack to free it.
211 : * In this case the core stack will free the packet.
212 : * - NET_OK, if the packet was accepted, in this case the ownership of the
213 : * net_pkt goes to callback and core network stack will forget it.
214 : */
215 : typedef enum net_verdict (*net_lldp_recv_cb_t)(struct net_if *iface,
216 : struct net_pkt *pkt);
217 :
218 : /**
219 : * @brief Register LLDP Rx callback function
220 : *
221 : * @param iface Network interface
222 : * @param cb Callback function
223 : *
224 : * @return 0 if ok, < 0 if error
225 : */
226 1 : int net_lldp_register_callback(struct net_if *iface, net_lldp_recv_cb_t cb);
227 :
228 : /**
229 : * @brief Parse LLDP packet
230 : *
231 : * @param iface Network interface
232 : * @param pkt Network packet
233 : *
234 : * @return Return the policy for network buffer
235 : */
236 1 : enum net_verdict net_lldp_recv(struct net_if *iface, struct net_pkt *pkt);
237 :
238 : /**
239 : * @brief Set LLDP protocol data unit (LLDPDU) for the network interface.
240 : *
241 : * @param iface Network interface
242 : *
243 : * @return <0 if error, index in lldp array if iface is found there
244 : */
245 : #if defined(CONFIG_NET_LLDP)
246 : int net_lldp_set_lldpdu(struct net_if *iface);
247 : #else
248 1 : #define net_lldp_set_lldpdu(iface)
249 : #endif
250 :
251 : /**
252 : * @brief Unset LLDP protocol data unit (LLDPDU) for the network interface.
253 : *
254 : * @param iface Network interface
255 : */
256 : #if defined(CONFIG_NET_LLDP)
257 : void net_lldp_unset_lldpdu(struct net_if *iface);
258 : #else
259 1 : #define net_lldp_unset_lldpdu(iface)
260 : #endif
261 :
262 : #ifdef __cplusplus
263 : }
264 : #endif
265 :
266 : /**
267 : * @}
268 : */
269 :
270 : #endif /* ZEPHYR_INCLUDE_NET_LLDP_H_ */
|