iPXE
Data Structures | Functions | Variables
lldp.c File Reference

Link Layer Discovery Protocol. More...

#include <stdlib.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 66 of file lldp.c.

67  {
68 
69  return ( setting->scope == &lldp_settings_scope );
70 }
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:57

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

83  {
84  struct lldp_settings *lldpset =
86  union {
87  uint32_t high;
88  uint8_t raw[4];
89  } tag_prefix;
90  uint32_t tag_low;
91  uint8_t tag_type;
92  uint8_t tag_index;
93  uint8_t tag_offset;
94  uint8_t tag_length;
95  const void *match;
96  const void *data;
97  size_t match_len;
98  size_t remaining;
99  const struct lldp_tlv *tlv;
100  unsigned int tlv_type_len;
101  unsigned int tlv_type;
102  unsigned int tlv_len;
103 
104  /* Parse setting tag */
105  tag_prefix.high = htonl ( setting->tag >> 32 );
106  tag_low = setting->tag;
107  tag_type = ( tag_low >> 24 );
108  tag_index = ( tag_low >> 16 );
109  tag_offset = ( tag_low >> 8 );
110  tag_length = ( tag_low >> 0 );
111 
112  /* Identify match prefix */
113  match_len = tag_offset;
114  if ( match_len > sizeof ( tag_prefix ) )
115  match_len = sizeof ( tag_prefix );
116  if ( ! tag_prefix.high )
117  match_len = 0;
118  match = &tag_prefix.raw[ sizeof ( tag_prefix ) - match_len ];
119 
120  /* Locate matching TLV */
121  for ( data = lldpset->data, remaining = lldpset->len ; remaining ;
122  data += tlv_len, remaining -= tlv_len ) {
123 
124  /* Parse TLV header */
125  if ( remaining < sizeof ( *tlv ) ) {
126  DBGC ( lldpset, "LLDP %s underlength TLV header\n",
127  lldpset->name );
128  DBGC_HDA ( lldpset, 0, data, remaining );
129  break;
130  }
131  tlv = data;
132  data += sizeof ( *tlv );
133  remaining -= sizeof ( *tlv );
134  tlv_type_len = ntohs ( tlv->type_len );
135  tlv_type = LLDP_TLV_TYPE ( tlv_type_len );
136  if ( tlv_type == LLDP_TYPE_END )
137  break;
138  tlv_len = LLDP_TLV_LEN ( tlv_type_len );
139  if ( remaining < tlv_len ) {
140  DBGC ( lldpset, "LLDP %s underlength TLV value\n",
141  lldpset->name );
142  DBGC_HDA ( lldpset, 0, data, remaining );
143  break;
144  }
145  DBGC2 ( lldpset, "LLDP %s found type %d:\n",
146  lldpset->name, tlv_type );
147  DBGC2_HDA ( lldpset, 0, data, tlv_len );
148 
149  /* Check for matching tag type */
150  if ( tlv_type != tag_type )
151  continue;
152 
153  /* Check for matching prefix */
154  if ( tlv_len < match_len )
155  continue;
156  if ( memcmp ( data, match, match_len ) != 0 )
157  continue;
158 
159  /* Check for matching index */
160  if ( tag_index-- )
161  continue;
162 
163  /* Skip offset */
164  if ( tlv_len < tag_offset )
165  return 0;
166  data += tag_offset;
167  tlv_len -= tag_offset;
168 
169  /* Set type if not already specified */
170  if ( ! setting->type ) {
171  setting->type = ( tag_length ? &setting_type_hex :
172  &setting_type_string );
173  }
174 
175  /* Extract value */
176  if ( tag_length && ( tlv_len > tag_length ) )
177  tlv_len = tag_length;
178  if ( len > tlv_len )
179  len = tlv_len;
180  memcpy ( buf, data, len );
181  return tlv_len;
182  }
183 
184  return -ENOENT;
185 }
struct eth_slow_tlv_header tlv
TLV header.
Definition: eth_slow.h:12
size_t len
Length of LLDP data.
Definition: lldp.c:50
void * data
LLDP data.
Definition: lldp.c:48
#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
const char * name
Name.
Definition: lldp.c:46
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:42
A setting.
Definition: settings.h:23
uint32_t len
Length.
Definition: ena.h:14
#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, len, lldp_settings::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 203 of file lldp.c.

205  {
206  struct lldp_settings *lldpset;
207  size_t len;
208  void *data;
209  int rc;
210 
211  /* Find matching LLDP settings block */
212  lldpset = netdev_priv ( netdev, &lldp_driver );
213 
214  /* Create trimmed copy of received LLDP data */
215  len = iob_len ( iobuf );
216  data = malloc ( len );
217  if ( ! data ) {
218  rc = -ENOMEM;
219  goto err_alloc;
220  }
221  memcpy ( data, iobuf->data, len );
222 
223  /* Free any existing LLDP data */
224  free ( lldpset->data );
225 
226  /* Transfer data to LLDP settings block */
227  lldpset->data = data;
228  lldpset->len = len;
229  data = NULL;
230  DBGC2 ( lldpset, "LLDP %s src %s ",
231  lldpset->name, netdev->ll_protocol->ntoa ( ll_source ) );
232  DBGC2 ( lldpset, "dst %s\n", netdev->ll_protocol->ntoa ( ll_dest ) );
233  DBGC2_HDA ( lldpset, 0, lldpset->data, lldpset->len );
234 
235  /* Success */
236  rc = 0;
237 
238  free ( data );
239  err_alloc:
240  free_iob ( iobuf );
241  return rc;
242 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
size_t len
Length of LLDP data.
Definition: lldp.c:50
void * data
LLDP data.
Definition: lldp.c:48
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
#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
static struct net_device * netdev
Definition: gdbudp.c:52
const char * name
Name.
Definition: lldp.c:46
#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:155
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
An LLDP settings block.
Definition: lldp.c:42
uint32_t len
Length.
Definition: ena.h:14
#define DBGC2(...)
Definition: compiler.h:522
void * data
Start of data.
Definition: iobuf.h:48
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, io_buffer::data, lldp_settings::data, DBGC2, DBGC2_HDA, ENOMEM, free, free_iob(), iob_len(), len, lldp_settings::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 258 of file lldp.c.

258  {
259  struct lldp_settings *lldpset = priv;
260  int rc;
261 
262  /* Initialise LLDP settings block */
265  lldpset->name = netdev->name;
266 
267  /* Register settings */
268  if ( ( rc = register_settings ( &lldpset->settings,
270  LLDP_SETTINGS_NAME ) ) != 0 ) {
271  DBGC ( lldpset, "LLDP %s could not register settings: %s\n",
272  lldpset->name, strerror ( rc ) );
273  goto err_register;
274  }
275  DBGC ( lldpset, "LLDP %s registered\n", lldpset->name );
276 
277  return 0;
278 
279  unregister_settings ( &lldpset->settings );
280  err_register:
281  assert ( lldpset->data == NULL );
282  return rc;
283 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void * data
LLDP data.
Definition: lldp.c:48
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:583
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:500
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:46
struct settings settings
Settings interface.
Definition: lldp.c:44
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:42
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
static struct tlan_private * priv
Definition: tlan.c:224
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:57
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
static struct settings_operations lldp_settings_operations
LLDP settings operations.
Definition: lldp.c:188

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

291  {
292  struct lldp_settings *lldpset = priv;
293 
294  /* Unregister settings */
295  unregister_settings ( &lldpset->settings );
296  DBGC ( lldpset, "LLDP %s unregistered\n", lldpset->name );
297 
298  /* Free any LLDP data */
299  free ( lldpset->data );
300  lldpset->data = NULL;
301 }
void * data
LLDP data.
Definition: lldp.c:48
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:46
struct settings settings
Settings interface.
Definition: lldp.c:44
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
An LLDP settings block.
Definition: lldp.c:42
static struct tlan_private * priv
Definition: tlan.c:224
#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:258
static void lldp_remove(struct net_device *netdev __unused, void *priv)
Remove LLDP settings block.
Definition: lldp.c:291
An LLDP settings block.
Definition: lldp.c:42

LLDP driver.

Definition at line 54 of file lldp.c.

◆ lldp_settings_scope

const struct settings_scope lldp_settings_scope
static

LLDP settings scope.

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

LLDP settings operations.

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

LLDP protocol.

AoE protocol.

Definition at line 245 of file lldp.c.