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

◆ 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 67 of file lldp.c.

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

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 82 of file lldp.c.

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

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 204 of file lldp.c.

206  {
207  struct lldp_settings *lldpset;
208  size_t len;
209  void *data;
210  int rc;
211 
212  /* Find matching LLDP settings block */
213  lldpset = netdev_priv ( netdev, &lldp_driver );
214 
215  /* Create trimmed copy of received LLDP data */
216  len = iob_len ( iobuf );
217  data = malloc ( len );
218  if ( ! data ) {
219  rc = -ENOMEM;
220  goto err_alloc;
221  }
222  memcpy ( data, iobuf->data, len );
223 
224  /* Free any existing LLDP data */
225  free ( lldpset->data );
226 
227  /* Transfer data to LLDP settings block */
228  lldpset->data = data;
229  lldpset->len = len;
230  data = NULL;
231  DBGC2 ( lldpset, "LLDP %s src %s ",
232  lldpset->name, netdev->ll_protocol->ntoa ( ll_source ) );
233  DBGC2 ( lldpset, "dst %s\n", netdev->ll_protocol->ntoa ( ll_dest ) );
234  DBGC2_HDA ( lldpset, 0, lldpset->data, lldpset->len );
235 
236  /* Success */
237  rc = 0;
238 
239  free ( data );
240  err_alloc:
241  free_iob ( iobuf );
242  return rc;
243 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
size_t len
Length of LLDP data.
Definition: lldp.c:51
void * data
LLDP data.
Definition: lldp.c:49
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:152
#define ENOMEM
Not enough space.
Definition: errno.h:534
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:152
ring len
Length.
Definition: dwmac.h:231
static struct net_device * netdev
Definition: gdbudp.c:52
const char * name
Name.
Definition: lldp.c:47
#define DBGC2_HDA(...)
Definition: compiler.h:523
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:159
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:620
An LLDP settings block.
Definition: lldp.c:43
#define DBGC2(...)
Definition: compiler.h:522
void * data
Start of data.
Definition: iobuf.h:52
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:163
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:372

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 259 of file lldp.c.

259  {
260  struct lldp_settings *lldpset = priv;
261  int rc;
262 
263  /* Initialise LLDP settings block */
266  lldpset->name = netdev->name;
267 
268  /* Register settings */
269  if ( ( rc = register_settings ( &lldpset->settings,
271  LLDP_SETTINGS_NAME ) ) != 0 ) {
272  DBGC ( lldpset, "LLDP %s could not register settings: %s\n",
273  lldpset->name, strerror ( rc ) );
274  goto err_register;
275  }
276  DBGC ( lldpset, "LLDP %s registered\n", lldpset->name );
277 
278  return 0;
279 
280  unregister_settings ( &lldpset->settings );
281  err_register:
282  assert ( lldpset->data == NULL );
283  return rc;
284 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void * data
LLDP data.
Definition: lldp.c:49
void unregister_settings(struct settings *settings)
Unregister settings block.
Definition: settings.c:514
#define DBGC(...)
Definition: compiler.h:505
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition: netdevice.h:586
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:502
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:47
struct settings settings
Settings interface.
Definition: lldp.c:45
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct refcnt refcnt
Reference counter.
Definition: netdevice.h:354
An LLDP settings block.
Definition: lldp.c:43
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
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:475
#define LLDP_SETTINGS_NAME
LLDP settings block name.
Definition: lldp.h:42
static const struct settings_scope lldp_settings_scope
LLDP settings scope.
Definition: lldp.c:58
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
static struct settings_operations lldp_settings_operations
LLDP settings operations.
Definition: lldp.c:189

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 292 of file lldp.c.

292  {
293  struct lldp_settings *lldpset = priv;
294 
295  /* Unregister settings */
296  unregister_settings ( &lldpset->settings );
297  DBGC ( lldpset, "LLDP %s unregistered\n", lldpset->name );
298 
299  /* Free any LLDP data */
300  free ( lldpset->data );
301  lldpset->data = NULL;
302 }
void * data
LLDP data.
Definition: lldp.c:49
void unregister_settings(struct settings *settings)
Unregister settings block.
Definition: settings.c:514
#define DBGC(...)
Definition: compiler.h:505
const char * name
Name.
Definition: lldp.c:47
struct settings settings
Settings interface.
Definition: lldp.c:45
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
An LLDP settings block.
Definition: lldp.c:43
static struct tlan_private * priv
Definition: tlan.c:225
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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:259
static void lldp_remove(struct net_device *netdev __unused, void *priv)
Remove LLDP settings block.
Definition: lldp.c:292
An LLDP settings block.
Definition: lldp.c:43

LLDP driver.

Definition at line 55 of file lldp.c.

◆ lldp_settings_scope

const struct settings_scope lldp_settings_scope
static

LLDP settings scope.

Definition at line 58 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:82
static int lldp_applies(struct settings *settings __unused, const struct setting *setting)
Check applicability of LLDP setting.
Definition: lldp.c:67

LLDP settings operations.

Definition at line 189 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:26
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:204
#define htons(value)
Definition: byteswap.h:135

LLDP protocol.

AoE protocol.

Definition at line 246 of file lldp.c.