From dc16de3204d1956d4fd17808e6d34ac926bbe932 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Sun, 5 Feb 2023 13:07:30 +0000 Subject: [lldp] Add support for the Link Layer Discovery Protocol Add support for recording LLDP packets and exposing TLV values via the settings mechanism. LLDP settings are encoded as ${netX.lldp/....} where is the TLV type is the starting offset within the TLV value is the length (or zero to read the from to the end) , if it has a non-zero value, is the subtype byte string of length to match at the start of the TLV value, up to a maximum matched length of 4 bytes is the index of the entry matching and to be accessed, with zero indicating the first matching entry The is designed to accommodate both matching of the OUI within an organization-specific TLV (e.g. 0x0080c2 for IEEE 802.1 TLVs) and of a subtype byte as found within many TLVs. This encoding allows most LLDP values to be extracted easily. For example System name: ${netX.lldp/5.0.0.0:string} System description: ${netX.lldp/6.0.0.0:string} Port description: ${netX.lldp/4.0.0.0:string} Port interface name: ${netX.lldp/5.2.0.1.0:string} Chassis MAC address: ${netX.lldp/4.1.0.1.0:hex} Management IPv4 address: ${netX.lldp/5.1.8.0.2.4:ipv4} Port VLAN ID: ${netX.lldp/0x0080c2.1.127.0.4.2:int16} Port VLAN name: ${netX.lldp/0x0080c2.3.127.0.7.0:string} Maximum frame size: ${netX.lldp/0x00120f.4.127.0.4.2:uint16} Originally-implemented-by: Marin Hannache Signed-off-by: Michael Brown --- src/include/ipxe/errfile.h | 1 + src/include/ipxe/if_ether.h | 1 + src/include/ipxe/lldp.h | 97 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+) create mode 100644 src/include/ipxe/lldp.h (limited to 'src/include') diff --git a/src/include/ipxe/errfile.h b/src/include/ipxe/errfile.h index 7c3b0c43b..d7b6ea1bd 100644 --- a/src/include/ipxe/errfile.h +++ b/src/include/ipxe/errfile.h @@ -295,6 +295,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #define ERRFILE_ntp ( ERRFILE_NET | 0x00490000 ) #define ERRFILE_httpntlm ( ERRFILE_NET | 0x004a0000 ) #define ERRFILE_eap ( ERRFILE_NET | 0x004b0000 ) +#define ERRFILE_lldp ( ERRFILE_NET | 0x004c0000 ) #define ERRFILE_image ( ERRFILE_IMAGE | 0x00000000 ) #define ERRFILE_elf ( ERRFILE_IMAGE | 0x00010000 ) diff --git a/src/include/ipxe/if_ether.h b/src/include/ipxe/if_ether.h index 58d91b976..c1168b10e 100644 --- a/src/include/ipxe/if_ether.h +++ b/src/include/ipxe/if_ether.h @@ -23,6 +23,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #define ETH_P_SLOW 0x8809 /* Ethernet slow protocols */ #define ETH_P_EAPOL 0x888E /* 802.1X EAP over LANs */ #define ETH_P_AOE 0x88A2 /* ATA over Ethernet */ +#define ETH_P_LLDP 0x88CC /* Link Layer Discovery Protocol */ #define ETH_P_FCOE 0x8906 /* Fibre Channel over Ethernet */ #define ETH_P_FIP 0x8914 /* FCoE Initialization Protocol */ diff --git a/src/include/ipxe/lldp.h b/src/include/ipxe/lldp.h new file mode 100644 index 000000000..9951d3b8f --- /dev/null +++ b/src/include/ipxe/lldp.h @@ -0,0 +1,97 @@ +#ifndef _IPXE_LLDP_H +#define _IPXE_LLDP_H + +/** @file + * + * Link Layer Discovery Protocol + * + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +#include + +/** An LLDP TLV header */ +struct lldp_tlv { + /** Type and length */ + uint16_t type_len; + /** Data */ + uint8_t data[0]; +} __attribute__ (( packed )); + +/** + * Extract LLDP TLV type + * + * @v type_len Type and length + * @ret type Type + */ +#define LLDP_TLV_TYPE( type_len ) ( (type_len) >> 9 ) + +/** + * Extract LLDP TLV length + * + * @v type_len Type and length + * @ret len Length + */ +#define LLDP_TLV_LEN( type_len ) ( (type_len) & 0x01ff ) + +/** End of LLDP data unit */ +#define LLDP_TYPE_END 0x00 + +/** LLDP settings block name */ +#define LLDP_SETTINGS_NAME "lldp" + +/** + * Construct LLDP setting tag + * + * LLDP settings are encoded as + * + * ${netX.lldp/....} + * + * where + * + * is the TLV type + * + * is the starting offset within the TLV value + * + * is the length (or zero to read the from to the end) + * + * , if it has a non-zero value, is the subtype byte string + * of length to match at the start of the TLV value, up to + * a maximum matched length of 4 bytes + * + * is the index of the entry matching and to + * be accessed, with zero indicating the first matching entry + * + * The is designed to accommodate both matching of the OUI + * within an organization-specific TLV (e.g. 0x0080c2 for IEEE 802.1 + * TLVs) and of a subtype byte as found within many TLVs. + * + * This encoding allows most LLDP values to be extracted easily. For + * example + * + * System name: ${netX.lldp/5.0.0.0:string} + * + * System description: ${netX.lldp/6.0.0.0:string} + * + * Port description: ${netX.lldp/4.0.0.0:string} + * + * Port interface name: ${netX.lldp/5.2.0.1.0:string} + * + * Chassis MAC address: ${netX.lldp/4.1.0.1.0:hex} + * + * Management IPv4 address: ${netX.lldp/5.1.8.0.2.4:ipv4} + * + * Port VLAN ID: ${netX.lldp/0x0080c2.1.127.0.4.2:int16} + * + * Port VLAN name: ${netX.lldp/0x0080c2.3.127.0.7.0:string} + * + * Maximum frame size: ${netX.lldp/0x00120f.4.127.0.4.2:uint16} + * + */ +#define LLDP_TAG( prefix, type, index, offset, length ) \ + ( ( ( ( uint64_t ) (prefix) ) << 32 ) | \ + ( (type) << 24 ) | ( (index) << 16 ) | \ + ( (offset) << 8 ) | ( (length) << 0 ) ) + +#endif /* _IPXE_LLDP_H */ -- cgit v1.2.3-55-g7522