zephyr/include/net/lldp.h

269 lines
7.5 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/** @file
@brief LLDP definitions and handler
This is not to be included by the application.
*/
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_NET_LLDP_H_
#define ZEPHYR_INCLUDE_NET_LLDP_H_
/**
* @brief LLDP definitions and helpers
* @defgroup lldp Link Layer Discovery Protocol definitions and helpers
* @ingroup networking
* @{
*/
#ifdef __cplusplus
extern "C" {
#endif
/** @cond INTERNAL_HIDDEN */
#define LLDP_TLV_GET_LENGTH(type_length) (type_length & BIT_MASK(9))
#define LLDP_TLV_GET_TYPE(type_length) ((uint8_t)(type_length >> 9))
/* LLDP Definitions */
/* According to the spec, End of LLDPDU TLV value is constant. */
#define NET_LLDP_END_LLDPDU_VALUE 0x0000
/*
* For the Chassis ID TLV Value, if subtype is a MAC address then we must
* use values from CONFIG_NET_LLDP_CHASSIS_ID_MAC0 through
* CONFIG_NET_LLDP_CHASSIS_ID_MAC5. If not, we use CONFIG_NET_LLDP_CHASSIS_ID.
*
* FIXME: implement a similar scheme for subtype 5 (network address).
*/
#if defined(CONFIG_NET_LLDP_CHASSIS_ID_SUBTYPE)
#if (CONFIG_NET_LLDP_CHASSIS_ID_SUBTYPE == 4)
#define NET_LLDP_CHASSIS_ID_VALUE \
{ \
CONFIG_NET_LLDP_CHASSIS_ID_MAC0, \
CONFIG_NET_LLDP_CHASSIS_ID_MAC1, \
CONFIG_NET_LLDP_CHASSIS_ID_MAC2, \
CONFIG_NET_LLDP_CHASSIS_ID_MAC3, \
CONFIG_NET_LLDP_CHASSIS_ID_MAC4, \
CONFIG_NET_LLDP_CHASSIS_ID_MAC5 \
}
#define NET_LLDP_CHASSIS_ID_VALUE_LEN (6)
#else
#define NET_LLDP_CHASSIS_ID_VALUE CONFIG_NET_LLDP_CHASSIS_ID
#define NET_LLDP_CHASSIS_ID_VALUE_LEN (sizeof(CONFIG_NET_LLDP_CHASSIS_ID) - 1)
#endif
#else
#define NET_LLDP_CHASSIS_ID_VALUE 0
#define NET_LLDP_CHASSIS_ID_VALUE_LEN 0
#endif
/*
* For the Port ID TLV Value, if subtype is a MAC address then we must
* use values from CONFIG_NET_LLDP_PORT_ID_MAC0 through
* CONFIG_NET_LLDP_PORT_ID_MAC5. If not, we use CONFIG_NET_LLDP_PORT_ID.
*
* FIXME: implement a similar scheme for subtype 4 (network address).
*/
#if defined(CONFIG_NET_LLDP_PORT_ID_SUBTYPE)
#if (CONFIG_NET_LLDP_PORT_ID_SUBTYPE == 3)
#define NET_LLDP_PORT_ID_VALUE \
{ \
CONFIG_NET_LLDP_PORT_ID_MAC0, \
CONFIG_NET_LLDP_PORT_ID_MAC1, \
CONFIG_NET_LLDP_PORT_ID_MAC2, \
CONFIG_NET_LLDP_PORT_ID_MAC3, \
CONFIG_NET_LLDP_PORT_ID_MAC4, \
CONFIG_NET_LLDP_PORT_ID_MAC5 \
}
#define NET_LLDP_PORT_ID_VALUE_LEN (6)
#else
#define NET_LLDP_PORT_ID_VALUE CONFIG_NET_LLDP_PORT_ID
#define NET_LLDP_PORT_ID_VALUE_LEN (sizeof(CONFIG_NET_LLDP_PORT_ID) - 1)
#endif
#else
#define NET_LLDP_PORT_ID_VALUE 0
#define NET_LLDP_PORT_ID_VALUE_LEN 0
#endif
/*
* TLVs Length.
* Note that TLVs that have a subtype must have a byte added to their length.
*/
#define NET_LLDP_CHASSIS_ID_TLV_LEN (NET_LLDP_CHASSIS_ID_VALUE_LEN + 1)
#define NET_LLDP_PORT_ID_TLV_LEN (NET_LLDP_PORT_ID_VALUE_LEN + 1)
#define NET_LLDP_TTL_TLV_LEN (2)
/*
* Time to Live value.
* Calculate based on section 9.2.5.22 from LLDP spec.
*
* FIXME: when the network interface is about to be disabled TTL shall be set
* to zero so LLDP Rx agents can invalidate the entry related to this node.
*/
#if defined(CONFIG_NET_LLDP_TX_INTERVAL) && defined(CONFIG_NET_LLDP_TX_HOLD)
#define NET_LLDP_TTL \
MIN((CONFIG_NET_LLDP_TX_INTERVAL * CONFIG_NET_LLDP_TX_HOLD) + 1, 65535)
#endif
struct net_if;
/** @endcond */
/** TLV Types. Please refer to table 8-1 from IEEE 802.1AB standard. */
enum net_lldp_tlv_type {
LLDP_TLV_END_LLDPDU = 0, /**< End Of LLDPDU (optional) */
LLDP_TLV_CHASSIS_ID = 1, /**< Chassis ID (mandatory) */
LLDP_TLV_PORT_ID = 2, /**< Port ID (mandatory) */
LLDP_TLV_TTL = 3, /**< Time To Live (mandatory) */
LLDP_TLV_PORT_DESC = 4, /**< Port Description (optional) */
LLDP_TLV_SYSTEM_NAME = 5, /**< System Name (optional) */
LLDP_TLV_SYSTEM_DESC = 6, /**< System Description (optional) */
LLDP_TLV_SYSTEM_CAPABILITIES = 7, /**< System Capability (optional) */
LLDP_TLV_MANAGEMENT_ADDR = 8, /**< Management Address (optional) */
/* Types 9 - 126 are reserved. */
LLDP_TLV_ORG_SPECIFIC = 127, /**< Org specific TLVs (optional) */
};
/** Chassis ID TLV, see chapter 8.5.2 in IEEE 802.1AB */
struct net_lldp_chassis_tlv {
/** 7 bits for type, 9 bits for length */
uint16_t type_length;
/** ID subtype */
uint8_t subtype;
/** Chassis ID value */
uint8_t value[NET_LLDP_CHASSIS_ID_VALUE_LEN];
} __packed;
/** Port ID TLV, see chapter 8.5.3 in IEEE 802.1AB */
struct net_lldp_port_tlv {
/** 7 bits for type, 9 bits for length */
uint16_t type_length;
/** ID subtype */
uint8_t subtype;
/** Port ID value */
uint8_t value[NET_LLDP_PORT_ID_VALUE_LEN];
} __packed;
/** Time To Live TLV, see chapter 8.5.4 in IEEE 802.1AB */
struct net_lldp_time_to_live_tlv {
/** 7 bits for type, 9 bits for length */
uint16_t type_length;
/** Time To Live (TTL) value */
uint16_t ttl;
} __packed;
/**
* LLDP Data Unit (LLDPDU) shall contain the following ordered TLVs
* as stated in "8.2 LLDPDU format" from the IEEE 802.1AB
*/
struct net_lldpdu {
struct net_lldp_chassis_tlv chassis_id; /**< Mandatory Chassis TLV */
struct net_lldp_port_tlv port_id; /**< Mandatory Port TLV */
struct net_lldp_time_to_live_tlv ttl; /**< Mandatory TTL TLV */
} __packed;
/**
* @brief Set the LLDP data unit for a network interface.
*
* @param iface Network interface
* @param lldpdu LLDP data unit struct
*
* @return 0 if ok, <0 if error
*/
int net_lldp_config(struct net_if *iface, const struct net_lldpdu *lldpdu);
/**
* @brief Set the Optional LLDP TLVs for a network interface.
*
* @param iface Network interface
* @param tlv LLDP optional TLVs following mandatory part
* @param len Length of the optional TLVs
*
* @return 0 if ok, <0 if error
*/
int net_lldp_config_optional(struct net_if *iface, const uint8_t *tlv,
size_t len);
/**
* @brief Initialize LLDP engine.
*/
void net_lldp_init(void);
/**
* @brief LLDP Receive packet callback
*
* Callback gets called upon receiving packet. It is responsible for
* freeing packet or indicating to the stack that it needs to free packet
* by returning correct net_verdict.
*
* Returns:
* - NET_DROP, if packet was invalid, rejected or we want the stack to free it.
* In this case the core stack will free the packet.
* - NET_OK, if the packet was accepted, in this case the ownership of the
* net_pkt goes to callback and core network stack will forget it.
*/
typedef enum net_verdict (*net_lldp_recv_cb_t)(struct net_if *iface,
struct net_pkt *pkt);
/**
* @brief Register LLDP Rx callback function
*
* @param iface Network interface
* @param cb Callback function
*
* @return 0 if ok, < 0 if error
*/
int net_lldp_register_callback(struct net_if *iface, net_lldp_recv_cb_t cb);
/**
* @brief Parse LLDP packet
*
* @param iface Network interface
* @param pkt Network packet
*
* @return Return the policy for network buffer
*/
enum net_verdict net_lldp_recv(struct net_if *iface, struct net_pkt *pkt);
/**
* @brief Set LLDP protocol data unit (LLDPDU) for the network interface.
*
* @param iface Network interface
*
* @return <0 if error, index in lldp array if iface is found there
*/
#if defined(CONFIG_NET_LLDP)
int net_lldp_set_lldpdu(struct net_if *iface);
#else
#define net_lldp_set_lldpdu(iface)
#endif
/**
* @brief Unset LLDP protocol data unit (LLDPDU) for the network interface.
*
* @param iface Network interface
*/
#if defined(CONFIG_NET_LLDP)
void net_lldp_unset_lldpdu(struct net_if *iface);
#else
#define net_lldp_unset_lldpdu(iface)
#endif
#ifdef __cplusplus
}
#endif
/**
* @}
*/
#endif /* ZEPHYR_INCLUDE_NET_LLDP_H_ */