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