iPXE
lldp.c File Reference

Link Layer Discovery Protocol. More...

#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <byteswap.h>
#include <ipxe/iobuf.h>
#include <ipxe/netdevice.h>
#include <ipxe/if_ether.h>
#include <ipxe/settings.h>
#include <ipxe/lldp.h>

Go to the source code of this file.

Data Structures

struct  lldp_settings
 An LLDP settings block. More...

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
static int lldp_applies (struct settings *settings __unused, const struct setting *setting)
 Check applicability of LLDP setting.
static int lldp_fetch (struct settings *settings, struct setting *setting, void *buf, size_t len)
 Fetch value of LLDP setting.
static int lldp_rx (struct io_buffer *iobuf, struct net_device *netdev, const void *ll_dest, const void *ll_source, unsigned int flags __unused)
 Process LLDP packet.
static int lldp_probe (struct net_device *netdev, void *priv)
 Create LLDP settings block.
static void lldp_remove (struct net_device *netdev __unused, void *priv)
 Remove LLDP settings block.

Variables

struct net_driver lldp_driver __net_driver
 LLDP driver.
static const struct settings_scope lldp_settings_scope
 LLDP settings scope.
static struct settings_operations lldp_settings_operations
 LLDP settings operations.
struct net_protocol lldp_protocol __net_protocol
 LLDP protocol.

Detailed Description

Link Layer Discovery Protocol.

Definition in file lldp.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ lldp_applies()

int lldp_applies ( struct settings *settings __unused,
const struct setting * setting )
static

Check applicability of LLDP setting.

Parameters
settingsSettings block
settingSetting to fetch
Return values
appliesSetting applies within this settings block

Definition at line 68 of file lldp.c.

69 {
70
71 return ( setting->scope == &lldp_settings_scope );
72}
static const struct settings_scope lldp_settings_scope
LLDP settings scope.
Definition lldp.c:59
A setting.
Definition settings.h:24
const struct settings_scope * scope
Setting scope (or NULL)
Definition settings.h:50

References __unused, lldp_settings_scope, and setting::scope.

◆ lldp_fetch()

int lldp_fetch ( struct settings * settings,
struct setting * setting,
void * buf,
size_t len )
static

Fetch value of LLDP setting.

Parameters
settingsSettings block
settingSetting to fetch
bufBuffer to fill with setting data
lenLength of buffer
Return values
lenLength of setting data, or negative error

Definition at line 83 of file lldp.c.

85 {
86 struct lldp_settings *lldpset =
88 union {
90 uint8_t raw[4];
91 } tag_prefix;
92 uint32_t tag_low;
93 uint8_t tag_type;
94 uint8_t tag_index;
95 uint8_t tag_offset;
96 uint8_t tag_length;
97 const void *match;
98 const void *data;
99 size_t match_len;
100 size_t remaining;
101 const struct lldp_tlv *tlv;
102 unsigned int tlv_type_len;
103 unsigned int tlv_type;
104 unsigned int tlv_len;
105
106 /* Parse setting tag */
107 tag_prefix.high = htonl ( setting->tag >> 32 );
108 tag_low = setting->tag;
109 tag_type = ( tag_low >> 24 );
110 tag_index = ( tag_low >> 16 );
111 tag_offset = ( tag_low >> 8 );
112 tag_length = ( tag_low >> 0 );
113
114 /* Identify match prefix */
115 match_len = tag_offset;
116 if ( match_len > sizeof ( tag_prefix ) )
117 match_len = sizeof ( tag_prefix );
118 if ( ! tag_prefix.high )
119 match_len = 0;
120 match = &tag_prefix.raw[ sizeof ( tag_prefix ) - match_len ];
121
122 /* Locate matching TLV */
123 for ( data = lldpset->data, remaining = lldpset->len ; remaining ;
124 data += tlv_len, remaining -= tlv_len ) {
125
126 /* Parse TLV header */
127 if ( remaining < sizeof ( *tlv ) ) {
128 DBGC ( lldpset, "LLDP %s underlength TLV header\n",
129 lldpset->name );
130 DBGC_HDA ( lldpset, 0, data, remaining );
131 break;
132 }
133 tlv = data;
134 data += sizeof ( *tlv );
135 remaining -= sizeof ( *tlv );
136 tlv_type_len = ntohs ( tlv->type_len );
137 tlv_type = LLDP_TLV_TYPE ( tlv_type_len );
138 if ( tlv_type == LLDP_TYPE_END )
139 break;
140 tlv_len = LLDP_TLV_LEN ( tlv_type_len );
141 if ( remaining < tlv_len ) {
142 DBGC ( lldpset, "LLDP %s underlength TLV value\n",
143 lldpset->name );
144 DBGC_HDA ( lldpset, 0, data, remaining );
145 break;
146 }
147 DBGC2 ( lldpset, "LLDP %s found type %d:\n",
148 lldpset->name, tlv_type );
149 DBGC2_HDA ( lldpset, 0, data, tlv_len );
150
151 /* Check for matching tag type */
152 if ( tlv_type != tag_type )
153 continue;
154
155 /* Check for matching prefix */
156 if ( tlv_len < match_len )
157 continue;
158 if ( memcmp ( data, match, match_len ) != 0 )
159 continue;
160
161 /* Check for matching index */
162 if ( tag_index-- )
163 continue;
164
165 /* Skip offset */
166 if ( tlv_len < tag_offset )
167 return 0;
168 data += tag_offset;
169 tlv_len -= tag_offset;
170
171 /* Set type if not already specified */
172 if ( ! setting->type ) {
173 setting->type = ( tag_length ? &setting_type_hex :
174 &setting_type_string );
175 }
176
177 /* Extract value */
178 if ( tag_length && ( tlv_len > tag_length ) )
179 tlv_len = tag_length;
180 if ( len > tlv_len )
181 len = tlv_len;
182 memcpy ( buf, data, len );
183 return tlv_len;
184 }
185
186 return -ENOENT;
187}
__be32 raw[7]
Definition CIB_PRM.h:0
unsigned int uint32_t
Definition stdint.h:12
unsigned char uint8_t
Definition stdint.h:10
ring len
Length.
Definition dwmac.h:226
uint8_t data[48]
Additional event data.
Definition ena.h:11
#define DBGC2(...)
Definition compiler.h:522
#define DBGC2_HDA(...)
Definition compiler.h:523
#define DBGC(...)
Definition compiler.h:505
#define DBGC_HDA(...)
Definition compiler.h:506
#define ENOENT
No such file or directory.
Definition errno.h:515
#define htonl(value)
Definition byteswap.h:134
#define ntohs(value)
Definition byteswap.h:137
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define LLDP_TLV_LEN(type_len)
Extract LLDP TLV length.
Definition lldp.h:37
#define LLDP_TYPE_END
End of LLDP data unit.
Definition lldp.h:40
#define LLDP_TLV_TYPE(type_len)
Extract LLDP TLV type.
Definition lldp.h:29
uint32_t high
High 32 bits of address.
Definition myson.h:1
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115
An LLDP settings block.
Definition lldp.c:44
void * data
LLDP data.
Definition lldp.c:50
const char * name
Name.
Definition lldp.c:48
size_t len
Length of LLDP data.
Definition lldp.c:52
An LLDP TLV header.
Definition lldp.h:16
const struct setting_type * type
Setting type.
Definition settings.h:37
uint64_t tag
Setting tag, if applicable.
Definition settings.h:44
A settings block.
Definition settings.h:133
Definition bnxt_hsi.h:52

References container_of, data, lldp_settings::data, DBGC, DBGC2, DBGC2_HDA, DBGC_HDA, ENOENT, high, htonl, len, lldp_settings::len, LLDP_TLV_LEN, LLDP_TLV_TYPE, LLDP_TYPE_END, memcmp(), memcpy(), lldp_settings::name, ntohs, raw, setting::tag, and setting::type.

◆ lldp_rx()

int lldp_rx ( struct io_buffer * iobuf,
struct net_device * netdev,
const void * ll_dest,
const void * ll_source,
unsigned int flags __unused )
static

Process LLDP packet.

Parameters
iobufI/O buffer
netdevNetwork device
ll_destLink-layer destination address
ll_sourceLink-layer source address
flagsPacket flags
Return values
rcReturn status code

Definition at line 205 of file lldp.c.

207 {
208 struct lldp_settings *lldpset;
209 size_t len;
210 void *data;
211 int rc;
212
213 /* Find matching LLDP settings block */
214 lldpset = netdev_priv ( netdev, &lldp_driver );
215
216 /* Create trimmed copy of received LLDP data */
217 len = iob_len ( iobuf );
218 data = malloc ( len );
219 if ( ! data ) {
220 rc = -ENOMEM;
221 goto err_alloc;
222 }
223 memcpy ( data, iobuf->data, len );
224
225 /* Free any existing LLDP data */
226 free ( lldpset->data );
227
228 /* Transfer data to LLDP settings block */
229 lldpset->data = data;
230 lldpset->len = len;
231 data = NULL;
232 DBGC2 ( lldpset, "LLDP %s src %s ",
233 lldpset->name, netdev->ll_protocol->ntoa ( ll_source ) );
234 DBGC2 ( lldpset, "dst %s\n", netdev->ll_protocol->ntoa ( ll_dest ) );
235 DBGC2_HDA ( lldpset, 0, lldpset->data, lldpset->len );
236
237 /* Success */
238 rc = 0;
239
240 free ( data );
241 err_alloc:
242 free_iob ( iobuf );
243 return rc;
244}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
static struct net_device * netdev
Definition gdbudp.c:53
#define ENOMEM
Not enough space.
Definition errno.h:535
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:621
void * netdev_priv(struct net_device *netdev, struct net_driver *driver)
Get network device driver private data.
Definition netdevice.c:153
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
void * data
Start of data.
Definition iobuf.h:53

References __unused, data, io_buffer::data, lldp_settings::data, DBGC2, DBGC2_HDA, ENOMEM, flags, free, free_iob(), iob_len(), len, lldp_settings::len, malloc(), memcpy(), lldp_settings::name, netdev, netdev_priv(), NULL, and rc.

◆ lldp_probe()

int lldp_probe ( struct net_device * netdev,
void * priv )
static

Create LLDP settings block.

Parameters
netdevNetwork device
privPrivate data
Return values
rcReturn status code

Definition at line 260 of file lldp.c.

260 {
261 struct lldp_settings *lldpset = priv;
262 int rc;
263
264 /* Initialise LLDP settings block */
266 &netdev->refcnt, &lldp_settings_scope );
267 lldpset->name = netdev->name;
268
269 /* Register settings */
270 if ( ( rc = register_settings ( &lldpset->settings,
272 LLDP_SETTINGS_NAME ) ) != 0 ) {
273 DBGC ( lldpset, "LLDP %s could not register settings: %s\n",
274 lldpset->name, strerror ( rc ) );
275 goto err_register;
276 }
277 DBGC ( lldpset, "LLDP %s registered\n", lldpset->name );
278
279 return 0;
280
281 unregister_settings ( &lldpset->settings );
282 err_register:
283 assert ( lldpset->data == NULL );
284 return rc;
285}
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
static void settings_init(struct settings *settings, struct settings_operations *op, struct refcnt *refcnt, const struct settings_scope *default_scope)
Initialise a settings block.
Definition settings.h:503
static struct settings_operations lldp_settings_operations
LLDP settings operations.
Definition lldp.c:190
#define LLDP_SETTINGS_NAME
LLDP settings block name.
Definition lldp.h:43
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition netdevice.h:587
int register_settings(struct settings *settings, struct settings *parent, const char *name)
Register settings block.
Definition settings.c:476
void unregister_settings(struct settings *settings)
Unregister settings block.
Definition settings.c:515
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
struct settings settings
Settings interface.
Definition lldp.c:46
static struct tlan_private * priv
Definition tlan.c:225

References assert, lldp_settings::data, DBGC, LLDP_SETTINGS_NAME, lldp_settings_operations, lldp_settings_scope, lldp_settings::name, netdev, netdev_settings(), NULL, priv, rc, register_settings(), lldp_settings::settings, settings_init(), strerror(), and unregister_settings().

◆ lldp_remove()

void lldp_remove ( struct net_device *netdev __unused,
void * priv )
static

Remove LLDP settings block.

Parameters
netdevNetwork device
privPrivate data

Definition at line 293 of file lldp.c.

293 {
294 struct lldp_settings *lldpset = priv;
295
296 /* Unregister settings */
297 unregister_settings ( &lldpset->settings );
298 DBGC ( lldpset, "LLDP %s unregistered\n", lldpset->name );
299
300 /* Free any LLDP data */
301 free ( lldpset->data );
302 lldpset->data = NULL;
303}

References __unused, lldp_settings::data, DBGC, free, lldp_settings::name, netdev, NULL, priv, lldp_settings::settings, and unregister_settings().

Variable Documentation

◆ __net_driver

struct net_driver lldp_driver __net_driver
Initial value:
= {
.name = "LLDP",
.priv_len = sizeof ( struct lldp_settings ),
.probe = lldp_probe,
.remove = lldp_remove,
}
static void lldp_remove(struct net_device *netdev __unused, void *priv)
Remove LLDP settings block.
Definition lldp.c:293
static int lldp_probe(struct net_device *netdev, void *priv)
Create LLDP settings block.
Definition lldp.c:260

LLDP driver.

Definition at line 56 of file lldp.c.

◆ lldp_settings_scope

const struct settings_scope lldp_settings_scope
static

LLDP settings scope.

Definition at line 59 of file lldp.c.

Referenced by lldp_applies(), and lldp_probe().

◆ lldp_settings_operations

struct settings_operations lldp_settings_operations
static
Initial value:
= {
.applies = lldp_applies,
.fetch = lldp_fetch,
}
static int lldp_fetch(struct settings *settings, struct setting *setting, void *buf, size_t len)
Fetch value of LLDP setting.
Definition lldp.c:83
static int lldp_applies(struct settings *settings __unused, const struct setting *setting)
Check applicability of LLDP setting.
Definition lldp.c:68

LLDP settings operations.

Definition at line 190 of file lldp.c.

190 {
191 .applies = lldp_applies,
192 .fetch = lldp_fetch,
193};

Referenced by lldp_probe().

◆ __net_protocol

struct net_protocol lldp_protocol __net_protocol
Initial value:
= {
.name = "LLDP",
.net_proto = htons ( ETH_P_LLDP ),
.rx = lldp_rx,
}
#define ETH_P_LLDP
Definition if_ether.h:27
#define htons(value)
Definition byteswap.h:136
static int lldp_rx(struct io_buffer *iobuf, struct net_device *netdev, const void *ll_dest, const void *ll_source, unsigned int flags __unused)
Process LLDP packet.
Definition lldp.c:205

LLDP protocol.

AoE protocol.

Definition at line 247 of file lldp.c.

247 {
248 .name = "LLDP",
249 .net_proto = htons ( ETH_P_LLDP ),
250 .rx = lldp_rx,
251};