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 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 struct net_lldp_chassis_tlv { 139 /** 7 bits for type, 9 bits for length */ 140 uint16_t type_length; 141 /** ID subtype */ 142 uint8_t subtype; 143 /** Chassis ID value */ 144 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 struct net_lldp_port_tlv { 149 /** 7 bits for type, 9 bits for length */ 150 uint16_t type_length; 151 /** ID subtype */ 152 uint8_t subtype; 153 /** Port ID value */ 154 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 struct net_lldp_time_to_live_tlv { 159 /** 7 bits for type, 9 bits for length */ 160 uint16_t type_length; 161 /** Time To Live (TTL) value */ 162 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 struct net_lldpdu { 170 struct net_lldp_chassis_tlv chassis_id; /**< Mandatory Chassis TLV */ 171 struct net_lldp_port_tlv port_id; /**< Mandatory Port TLV */ 172 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 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 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 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 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 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 #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 #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_ */ 271