iPXE
Data Structures | Functions | Variables
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. More...
 
static int lldp_fetch (struct settings *settings, struct setting *setting, void *buf, size_t len)
 Fetch value of LLDP setting. More...
 
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. More...
 
static int lldp_probe (struct net_device *netdev, void *priv)
 Create LLDP settings block. More...
 
static void lldp_remove (struct net_device *netdev __unused, void *priv)
 Remove LLDP settings block. More...
 

Variables

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

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()

static 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 }
A setting.
Definition: settings.h:24
const struct settings_scope * scope
Setting scope (or NULL)
Definition: settings.h:50
static const struct settings_scope lldp_settings_scope
LLDP settings scope.
Definition: lldp.c:59

References lldp_settings_scope, and setting::scope.

◆ lldp_fetch()

static 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 {
89  uint32_t high;
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 }
struct eth_slow_tlv_header tlv
TLV header.
Definition: eth_slow.h:13
size_t len
Length of LLDP data.
Definition: lldp.c:52
void * data
LLDP data.
Definition: lldp.c:50
#define DBGC(...)
Definition: compiler.h:505
#define ENOENT
No such file or directory.
Definition: errno.h:515
#define ntohs(value)
Definition: byteswap.h:137
#define htonl(value)
Definition: byteswap.h:134
uint64_t tag
Setting tag, if applicable.
Definition: settings.h:44
#define LLDP_TLV_LEN(type_len)
Extract LLDP TLV length.
Definition: lldp.h:37
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:36
#define DBGC_HDA(...)
Definition: compiler.h:506
#define LLDP_TYPE_END
End of LLDP data unit.
Definition: lldp.h:40
ring len
Length.
Definition: dwmac.h:231
const char * name
Name.
Definition: lldp.c:48
const struct setting_type * type
Setting type.
Definition: settings.h:37
uint32_t high
High 32 bits of address.
Definition: myson.h:20
#define DBGC2_HDA(...)
Definition: compiler.h:523
A settings block.
Definition: settings.h:133
unsigned char uint8_t
Definition: stdint.h:10
unsigned int uint32_t
Definition: stdint.h:12
Definition: bnxt_hsi.h:52
An LLDP settings block.
Definition: lldp.c:44
A setting.
Definition: settings.h:24
#define DBGC2(...)
Definition: compiler.h:522
#define LLDP_TLV_TYPE(type_len)
Extract LLDP TLV type.
Definition: lldp.h:29
uint8_t data[48]
Additional event data.
Definition: ena.h:22
__be32 raw[7]
Definition: CIB_PRM.h:28
An LLDP TLV header.
Definition: lldp.h:16
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:115

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

◆ lldp_rx()

static 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 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
size_t len
Length of LLDP data.
Definition: lldp.c:52
void * data
LLDP data.
Definition: lldp.c:50
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:153
#define ENOMEM
Not enough space.
Definition: errno.h:535
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * netdev_priv(struct net_device *netdev, struct net_driver *driver)
Get network device driver private data.
Definition: netdevice.c:153
ring len
Length.
Definition: dwmac.h:231
static struct net_device * netdev
Definition: gdbudp.c:52
const char * name
Name.
Definition: lldp.c:48
#define DBGC2_HDA(...)
Definition: compiler.h:523
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55
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
An LLDP settings block.
Definition: lldp.c:44
#define DBGC2(...)
Definition: compiler.h:522
void * data
Start of data.
Definition: iobuf.h:53
uint8_t data[48]
Additional event data.
Definition: ena.h:22
const char *(* ntoa)(const void *ll_addr)
Transcribe link-layer address.
Definition: netdevice.h:164
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:373

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

◆ lldp_probe()

static 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 */
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 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void * data
LLDP data.
Definition: lldp.c:50
void unregister_settings(struct settings *settings)
Unregister settings block.
Definition: settings.c:515
#define DBGC(...)
Definition: compiler.h:505
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition: netdevice.h:587
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
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static struct net_device * netdev
Definition: gdbudp.c:52
const char * name
Name.
Definition: lldp.c:48
struct settings settings
Settings interface.
Definition: lldp.c:46
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
struct refcnt refcnt
Reference counter.
Definition: netdevice.h:355
An LLDP settings block.
Definition: lldp.c:44
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:363
static struct tlan_private * priv
Definition: tlan.c:225
int register_settings(struct settings *settings, struct settings *parent, const char *name)
Register settings block.
Definition: settings.c:476
#define LLDP_SETTINGS_NAME
LLDP settings block name.
Definition: lldp.h:43
static const struct settings_scope lldp_settings_scope
LLDP settings scope.
Definition: lldp.c:59
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
static struct settings_operations lldp_settings_operations
LLDP settings operations.
Definition: lldp.c:190

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

◆ lldp_remove()

static 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 }
void * data
LLDP data.
Definition: lldp.c:50
void unregister_settings(struct settings *settings)
Unregister settings block.
Definition: settings.c:515
#define DBGC(...)
Definition: compiler.h:505
const char * name
Name.
Definition: lldp.c:48
struct settings settings
Settings interface.
Definition: lldp.c:46
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55
An LLDP settings block.
Definition: lldp.c:44
static struct tlan_private * priv
Definition: tlan.c:225
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

References lldp_settings::data, DBGC, free, lldp_settings::name, 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 int lldp_probe(struct net_device *netdev, void *priv)
Create LLDP settings block.
Definition: lldp.c:260
static void lldp_remove(struct net_device *netdev __unused, void *priv)
Remove LLDP settings block.
Definition: lldp.c:293
An LLDP settings block.
Definition: lldp.c:44

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.

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
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
#define htons(value)
Definition: byteswap.h:136

LLDP protocol.

AoE protocol.

Definition at line 247 of file lldp.c.