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

Virtual LANs. More...

#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <byteswap.h>
#include <ipxe/features.h>
#include <ipxe/if_ether.h>
#include <ipxe/ethernet.h>
#include <ipxe/netdevice.h>
#include <ipxe/iobuf.h>
#include <ipxe/vlan.h>

Go to the source code of this file.

Data Structures

struct  vlan_device
 VLAN device private data. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
 FILE_SECBOOT (PERMITTED)
 
 FEATURE (FEATURE_PROTOCOL, "VLAN", DHCP_EB_FEATURE_VLAN, 1)
 
static int vlan_open (struct net_device *netdev)
 Open VLAN device. More...
 
static void vlan_close (struct net_device *netdev)
 Close VLAN device. More...
 
static int vlan_transmit (struct net_device *netdev, struct io_buffer *iobuf)
 Transmit packet on VLAN device. More...
 
static void vlan_poll (struct net_device *netdev)
 Poll VLAN device. More...
 
static void vlan_irq (struct net_device *netdev, int enable)
 Enable/disable interrupts on VLAN device. More...
 
static void vlan_sync (struct net_device *netdev)
 Synchronise VLAN device. More...
 
struct net_devicevlan_find (struct net_device *trunk, unsigned int tag)
 Identify VLAN device. More...
 
static int vlan_rx (struct io_buffer *iobuf, struct net_device *trunk, const void *ll_dest, const void *ll_source, unsigned int flags __unused)
 Process incoming VLAN packet. More...
 
unsigned int vlan_tci (struct net_device *netdev)
 Get the VLAN tag control information. More...
 
int vlan_can_be_trunk (struct net_device *trunk)
 Check if network device can be used as a VLAN trunk device. More...
 
int vlan_create (struct net_device *trunk, unsigned int tag, unsigned int priority)
 Create VLAN device. More...
 
int vlan_destroy (struct net_device *netdev)
 Destroy VLAN device. More...
 
void vlan_auto (const void *ll_addr, unsigned int tag)
 Configure automatic VLAN device. More...
 
static int vlan_probe (struct net_device *trunk, void *priv __unused)
 Create automatic VLAN device. More...
 
static void vlan_notify (struct net_device *trunk, void *priv __unused)
 Handle trunk network device link state change. More...
 
static int vlan_remove_first (struct net_device *trunk)
 Destroy first VLAN device for a given trunk. More...
 
static void vlan_remove (struct net_device *trunk, void *priv __unused)
 Destroy all VLAN devices for a given trunk. More...
 
void vlan_netdev_rx (struct net_device *netdev, unsigned int tag, struct io_buffer *iobuf)
 Add VLAN tag-stripped packet to receive queue. More...
 
void vlan_netdev_rx_err (struct net_device *netdev, unsigned int tag, struct io_buffer *iobuf, int rc)
 Discard received VLAN tag-stripped packet. More...
 

Variables

struct net_protocol vlan_protocol __net_protocol
 VLAN protocol. More...
 
static uint8_t vlan_auto_ll_addr [ETH_ALEN]
 Automatic VLAN device link-layer address. More...
 
static unsigned int vlan_auto_tag
 Automatic VLAN tag. More...
 
static struct net_device_operations vlan_operations
 VLAN device operations. More...
 
struct net_driver vlan_driver __net_driver
 VLAN driver. More...
 

Detailed Description

Virtual LANs.

Definition in file vlan.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED  )

◆ FEATURE()

FEATURE ( FEATURE_PROTOCOL  ,
"VLAN"  ,
DHCP_EB_FEATURE_VLAN  ,
 
)

◆ vlan_open()

static int vlan_open ( struct net_device netdev)
static

Open VLAN device.

Parameters
netdevNetwork device
Return values
rcReturn status code

Definition at line 71 of file vlan.c.

71  {
72  struct vlan_device *vlan = netdev->priv;
73 
74  return netdev_open ( vlan->trunk );
75 }
struct net_device * trunk
Trunk network device.
Definition: vlan.c:52
VLAN device private data.
Definition: vlan.c:50
void * priv
Driver private data.
Definition: netdevice.h:432
static struct net_device * netdev
Definition: gdbudp.c:52
int netdev_open(struct net_device *netdev)
Open network device.
Definition: netdevice.c:862

References netdev, netdev_open(), net_device::priv, and vlan_device::trunk.

◆ vlan_close()

static void vlan_close ( struct net_device netdev)
static

Close VLAN device.

Parameters
netdevNetwork device

Definition at line 82 of file vlan.c.

82  {
83  struct vlan_device *vlan = netdev->priv;
84 
85  netdev_close ( vlan->trunk );
86 }
struct net_device * trunk
Trunk network device.
Definition: vlan.c:52
VLAN device private data.
Definition: vlan.c:50
void * priv
Driver private data.
Definition: netdevice.h:432
static struct net_device * netdev
Definition: gdbudp.c:52
void netdev_close(struct net_device *netdev)
Close network device.
Definition: netdevice.c:896

References netdev, netdev_close(), net_device::priv, and vlan_device::trunk.

◆ vlan_transmit()

static int vlan_transmit ( struct net_device netdev,
struct io_buffer iobuf 
)
static

Transmit packet on VLAN device.

Parameters
netdevNetwork device
iobufI/O buffer
Return values
rcReturn status code

Definition at line 95 of file vlan.c.

96  {
97  struct vlan_device *vlan = netdev->priv;
98  struct net_device *trunk = vlan->trunk;
99  struct ll_protocol *ll_protocol;
100  struct vlan_header *vlanhdr;
101  uint8_t ll_dest_copy[ETH_ALEN];
102  uint8_t ll_source_copy[ETH_ALEN];
103  const void *ll_dest;
104  const void *ll_source;
106  unsigned int flags;
107  int rc;
108 
109  /* Strip link-layer header and preserve link-layer header fields */
111  if ( ( rc = ll_protocol->pull ( netdev, iobuf, &ll_dest, &ll_source,
112  &net_proto, &flags ) ) != 0 ) {
113  DBGC ( netdev, "VLAN %s could not parse link-layer header: "
114  "%s\n", netdev->name, strerror ( rc ) );
115  return rc;
116  }
117  memcpy ( ll_dest_copy, ll_dest, ETH_ALEN );
118  memcpy ( ll_source_copy, ll_source, ETH_ALEN );
119 
120  /* Construct VLAN header */
121  vlanhdr = iob_push ( iobuf, sizeof ( *vlanhdr ) );
122  vlanhdr->tci = htons ( VLAN_TCI ( vlan->tag, vlan->priority ) );
123  vlanhdr->net_proto = net_proto;
124 
125  /* Reclaim I/O buffer from VLAN device's TX queue */
126  list_del ( &iobuf->list );
127 
128  /* Transmit packet on trunk device */
129  if ( ( rc = net_tx ( iob_disown ( iobuf ), trunk, &vlan_protocol,
130  ll_dest_copy, ll_source_copy ) ) != 0 ) {
131  DBGC ( netdev, "VLAN %s could not transmit: %s\n",
132  netdev->name, strerror ( rc ) );
133  /* Cannot return an error status, since that would
134  * cause the I/O buffer to be double-freed.
135  */
136  return 0;
137  }
138 
139  return 0;
140 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned short uint16_t
Definition: stdint.h:11
uint16_t tci
Tag control information.
Definition: vlan.h:19
struct net_device * trunk
Trunk network device.
Definition: vlan.c:52
#define VLAN_TCI(tag, priority)
Construct VLAN tag control information.
Definition: vlan.h:47
uint16_t net_proto
Encapsulated protocol.
Definition: vlan.h:21
#define iob_push(iobuf, len)
Definition: iobuf.h:89
VLAN device private data.
Definition: vlan.c:50
#define DBGC(...)
Definition: compiler.h:505
A link-layer protocol.
Definition: netdevice.h:115
#define list_del(list)
Delete an entry from a list.
Definition: list.h:120
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:217
void * memcpy(void *dest, const void *src, size_t len) __nonnull
A VLAN header.
Definition: vlan.h:17
void * priv
Driver private data.
Definition: netdevice.h:432
static struct net_device * netdev
Definition: gdbudp.c:52
uint8_t flags
Flags.
Definition: ena.h:18
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
A network device.
Definition: netdevice.h:353
unsigned char uint8_t
Definition: stdint.h:10
#define ETH_ALEN
Definition: if_ether.h:9
unsigned int tag
VLAN tag.
Definition: vlan.c:54
int(* pull)(struct net_device *netdev, struct io_buffer *iobuf, const void **ll_dest, const void **ll_source, uint16_t *net_proto, unsigned int *flags)
Remove link-layer header.
Definition: netdevice.h:142
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:363
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:45
int net_tx(struct io_buffer *iobuf, struct net_device *netdev, struct net_protocol *net_protocol, const void *ll_dest, const void *ll_source)
Transmit network-layer packet.
Definition: netdevice.c:1074
unsigned int priority
Default priority.
Definition: vlan.c:56
#define htons(value)
Definition: byteswap.h:136
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:373

References DBGC, ETH_ALEN, flags, htons, iob_disown, iob_push, io_buffer::list, list_del, net_device::ll_protocol, memcpy(), net_device::name, vlan_header::net_proto, net_tx(), netdev, vlan_device::priority, net_device::priv, ll_protocol::pull, rc, strerror(), vlan_device::tag, vlan_header::tci, vlan_device::trunk, and VLAN_TCI.

◆ vlan_poll()

static void vlan_poll ( struct net_device netdev)
static

Poll VLAN device.

Parameters
netdevNetwork device

Definition at line 147 of file vlan.c.

147  {
148  struct vlan_device *vlan = netdev->priv;
149 
150  /* Poll trunk device */
151  netdev_poll ( vlan->trunk );
152 }
struct net_device * trunk
Trunk network device.
Definition: vlan.c:52
VLAN device private data.
Definition: vlan.c:50
void * priv
Driver private data.
Definition: netdevice.h:432
static struct net_device * netdev
Definition: gdbudp.c:52
void netdev_poll(struct net_device *netdev)
Poll for completed and received packets on network device.
Definition: netdevice.c:613

References netdev, netdev_poll(), net_device::priv, and vlan_device::trunk.

◆ vlan_irq()

static void vlan_irq ( struct net_device netdev,
int  enable 
)
static

Enable/disable interrupts on VLAN device.

Parameters
netdevNetwork device
enableInterrupts should be enabled

Definition at line 160 of file vlan.c.

160  {
161  struct vlan_device *vlan = netdev->priv;
162 
163  /* Enable/disable interrupts on trunk device. This is not at
164  * all robust, but there is no sensible course of action
165  * available.
166  */
167  netdev_irq ( vlan->trunk, enable );
168 }
struct net_device * trunk
Trunk network device.
Definition: vlan.c:52
VLAN device private data.
Definition: vlan.c:50
void * priv
Driver private data.
Definition: netdevice.h:432
static struct net_device * netdev
Definition: gdbudp.c:52
void netdev_irq(struct net_device *netdev, int enable)
Enable or disable interrupts.
Definition: netdevice.c:971

References netdev, netdev_irq(), net_device::priv, and vlan_device::trunk.

◆ vlan_sync()

static void vlan_sync ( struct net_device netdev)
static

Synchronise VLAN device.

Parameters
netdevNetwork device

Definition at line 184 of file vlan.c.

184  {
185  struct vlan_device *vlan = netdev->priv;
186  struct net_device *trunk = vlan->trunk;
187 
188  /* Synchronise link status */
189  if ( netdev->link_rc != trunk->link_rc )
190  netdev_link_err ( netdev, trunk->link_rc );
191 
192  /* Synchronise open/closed status */
193  if ( netdev_is_open ( trunk ) ) {
194  if ( ! netdev_is_open ( netdev ) )
195  netdev_open ( netdev );
196  } else {
197  if ( netdev_is_open ( netdev ) )
198  netdev_close ( netdev );
199  }
200 }
struct net_device * trunk
Trunk network device.
Definition: vlan.c:52
VLAN device private data.
Definition: vlan.c:50
static int netdev_is_open(struct net_device *netdev)
Check whether or not network device is open.
Definition: netdevice.h:662
int link_rc
Link status code.
Definition: netdevice.h:402
void * priv
Driver private data.
Definition: netdevice.h:432
static struct net_device * netdev
Definition: gdbudp.c:52
A network device.
Definition: netdevice.h:353
void netdev_link_err(struct net_device *netdev, int rc)
Mark network device as having a specific link state.
Definition: netdevice.c:208
void netdev_close(struct net_device *netdev)
Close network device.
Definition: netdevice.c:896
int netdev_open(struct net_device *netdev)
Open network device.
Definition: netdevice.c:862

References net_device::link_rc, netdev, netdev_close(), netdev_is_open(), netdev_link_err(), netdev_open(), net_device::priv, and vlan_device::trunk.

Referenced by vlan_create(), and vlan_notify().

◆ vlan_find()

struct net_device* vlan_find ( struct net_device trunk,
unsigned int  tag 
)

Identify VLAN device.

Parameters
trunkTrunk network device
tagVLAN tag
Return values
netdevVLAN device, if any

Definition at line 209 of file vlan.c.

209  {
210  struct net_device *netdev;
211  struct vlan_device *vlan;
212 
213  for_each_netdev ( netdev ) {
214  if ( netdev->op != &vlan_operations )
215  continue;
216  vlan = netdev->priv;
217  if ( ( vlan->trunk == trunk ) && ( vlan->tag == tag ) )
218  return netdev;
219  }
220  return NULL;
221 }
struct net_device * trunk
Trunk network device.
Definition: vlan.c:52
static struct net_device_operations vlan_operations
VLAN device operations.
Definition: vlan.c:171
VLAN device private data.
Definition: vlan.c:50
struct net_device_operations * op
Network device operations.
Definition: netdevice.h:370
void * priv
Driver private data.
Definition: netdevice.h:432
static struct net_device * netdev
Definition: gdbudp.c:52
#define for_each_netdev(netdev)
Iterate over all network devices.
Definition: netdevice.h:547
A network device.
Definition: netdevice.h:353
unsigned int tag
VLAN tag.
Definition: vlan.c:54
uint64_t tag
Identity tag.
Definition: edd.h:31
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

References for_each_netdev, netdev, NULL, net_device::op, net_device::priv, tag, vlan_device::tag, vlan_device::trunk, and vlan_operations.

Referenced by efi_vlan_find(), efi_vlan_remove(), vlan_create(), vlan_netdev_rx(), vlan_netdev_rx_err(), and vlan_rx().

◆ vlan_rx()

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

Process incoming VLAN packet.

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

Definition at line 233 of file vlan.c.

235  {
236  struct vlan_header *vlanhdr = iobuf->data;
237  struct net_device *netdev;
238  struct ll_protocol *ll_protocol;
239  uint8_t ll_dest_copy[ETH_ALEN];
240  uint8_t ll_source_copy[ETH_ALEN];
241  uint16_t tag;
242  int rc;
243 
244  /* Sanity check */
245  if ( iob_len ( iobuf ) < sizeof ( *vlanhdr ) ) {
246  DBGC ( trunk, "VLAN %s received underlength packet (%zd "
247  "bytes)\n", trunk->name, iob_len ( iobuf ) );
248  rc = -EINVAL;
249  goto err_sanity;
250  }
251 
252  /* Identify VLAN device */
253  tag = VLAN_TAG ( ntohs ( vlanhdr->tci ) );
254  netdev = vlan_find ( trunk, tag );
255  if ( ! netdev ) {
256  DBGC2 ( trunk, "VLAN %s received packet for unknown VLAN "
257  "%d\n", trunk->name, tag );
258  rc = -EPIPE;
259  goto err_no_vlan;
260  }
261 
262  /* Strip VLAN header and preserve original link-layer header fields */
263  iob_pull ( iobuf, sizeof ( *vlanhdr ) );
264  ll_protocol = trunk->ll_protocol;
265  memcpy ( ll_dest_copy, ll_dest, ETH_ALEN );
266  memcpy ( ll_source_copy, ll_source, ETH_ALEN );
267 
268  /* Reconstruct link-layer header for VLAN device */
270  if ( ( rc = ll_protocol->push ( netdev, iobuf, ll_dest_copy,
271  ll_source_copy,
272  vlanhdr->net_proto ) ) != 0 ) {
273  DBGC ( netdev, "VLAN %s could not reconstruct link-layer "
274  "header: %s\n", netdev->name, strerror ( rc ) );
275  goto err_ll_push;
276  }
277 
278  /* Enqueue packet on VLAN device */
279  netdev_rx ( netdev, iob_disown ( iobuf ) );
280  return 0;
281 
282  err_ll_push:
283  err_no_vlan:
284  err_sanity:
285  free_iob ( iobuf );
286  return rc;
287 }
#define iob_pull(iobuf, len)
Definition: iobuf.h:107
#define VLAN_TAG(tci)
Extract VLAN tag from tag control information.
Definition: vlan.h:30
#define EINVAL
Invalid argument.
Definition: errno.h:429
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned short uint16_t
Definition: stdint.h:11
uint16_t tci
Tag control information.
Definition: vlan.h:19
uint16_t net_proto
Encapsulated protocol.
Definition: vlan.h:21
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:153
#define EPIPE
Broken pipe.
Definition: errno.h:620
#define DBGC(...)
Definition: compiler.h:505
#define ntohs(value)
Definition: byteswap.h:137
A link-layer protocol.
Definition: netdevice.h:115
struct net_device * vlan_find(struct net_device *trunk, unsigned int tag)
Identify VLAN device.
Definition: vlan.c:209
int(* push)(struct net_device *netdev, struct io_buffer *iobuf, const void *ll_dest, const void *ll_source, uint16_t net_proto)
Add link-layer header.
Definition: netdevice.h:128
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:217
void * memcpy(void *dest, const void *src, size_t len) __nonnull
A VLAN header.
Definition: vlan.h:17
static struct net_device * netdev
Definition: gdbudp.c:52
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:160
A network device.
Definition: netdevice.h:353
unsigned char uint8_t
Definition: stdint.h:10
#define ETH_ALEN
Definition: if_ether.h:9
void netdev_rx(struct net_device *netdev, struct io_buffer *iobuf)
Add packet to receive queue.
Definition: netdevice.c:549
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:363
#define DBGC2(...)
Definition: compiler.h:522
void * data
Start of data.
Definition: iobuf.h:53
uint64_t tag
Identity tag.
Definition: edd.h:31
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:373

References io_buffer::data, DBGC, DBGC2, EINVAL, EPIPE, ETH_ALEN, free_iob(), iob_disown, iob_len(), iob_pull, net_device::ll_protocol, memcpy(), net_device::name, vlan_header::net_proto, netdev, netdev_rx(), ntohs, ll_protocol::push, rc, strerror(), tag, vlan_header::tci, vlan_find(), and VLAN_TAG.

◆ vlan_tci()

unsigned int vlan_tci ( struct net_device netdev)

Get the VLAN tag control information.

Parameters
netdevNetwork device
Return values
tciVLAN tag control information, or 0 if not a VLAN device

Definition at line 302 of file vlan.c.

302  {
303  struct vlan_device *vlan;
304 
305  if ( netdev->op == &vlan_operations ) {
306  vlan = netdev->priv;
307  return ( VLAN_TCI ( vlan->tag, vlan->priority ) );
308  } else {
309  return 0;
310  }
311 }
static struct net_device_operations vlan_operations
VLAN device operations.
Definition: vlan.c:171
#define VLAN_TCI(tag, priority)
Construct VLAN tag control information.
Definition: vlan.h:47
VLAN device private data.
Definition: vlan.c:50
struct net_device_operations * op
Network device operations.
Definition: netdevice.h:370
void * priv
Driver private data.
Definition: netdevice.h:432
static struct net_device * netdev
Definition: gdbudp.c:52
unsigned int tag
VLAN tag.
Definition: vlan.c:54
unsigned int priority
Default priority.
Definition: vlan.c:56

References netdev, net_device::op, vlan_device::priority, net_device::priv, vlan_device::tag, vlan_operations, and VLAN_TCI.

Referenced by vlan_tag().

◆ vlan_can_be_trunk()

int vlan_can_be_trunk ( struct net_device trunk)

Check if network device can be used as a VLAN trunk device.

Parameters
trunkTrunk network device
Return values
is_okTrunk network device is usable

VLAN devices will be created as Ethernet devices. (We cannot simply clone the link layer of the trunk network device, because this link layer may expect the network device structure to contain some link-layer-private data.) The trunk network device must therefore have a link layer that is in some sense 'compatible' with Ethernet; specifically, it must have link-layer addresses that are the same length as Ethernet link-layer addresses.

As an additional check, and primarily to assist with the sanity of the FCoE code, we refuse to allow nested VLANs.

Definition at line 330 of file vlan.c.

330  {
331 
332  return ( ( trunk->ll_protocol->ll_addr_len == ETH_ALEN ) &&
333  ( trunk->op != &vlan_operations ) );
334 }
struct net_device * trunk
Trunk network device.
Definition: vlan.c:52
uint8_t ll_addr_len
Link-layer address length.
Definition: netdevice.h:199
static struct net_device_operations vlan_operations
VLAN device operations.
Definition: vlan.c:171
struct net_device_operations * op
Network device operations.
Definition: netdevice.h:370
#define ETH_ALEN
Definition: if_ether.h:9
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:373

References ETH_ALEN, ll_protocol::ll_addr_len, net_device::ll_protocol, net_device::op, vlan_device::trunk, and vlan_operations.

Referenced by fcoe_expired(), fcoe_reset(), vlan_create(), and vlan_probe().

◆ vlan_create()

int vlan_create ( struct net_device trunk,
unsigned int  tag,
unsigned int  priority 
)

Create VLAN device.

Parameters
trunkTrunk network device
tagVLAN tag
priorityDefault VLAN priority
Return values
rcReturn status code

Definition at line 344 of file vlan.c.

345  {
346  struct net_device *netdev;
347  struct vlan_device *vlan;
348  int rc;
349 
350  /* If VLAN already exists, just update the priority */
351  if ( ( netdev = vlan_find ( trunk, tag ) ) != NULL ) {
352  vlan = netdev->priv;
353  if ( priority != vlan->priority ) {
354  DBGC ( netdev, "VLAN %s priority changed from %d to "
355  "%d\n", netdev->name, vlan->priority, priority );
356  }
357  vlan->priority = priority;
358  return 0;
359  }
360 
361  /* Sanity checks */
362  if ( ! vlan_can_be_trunk ( trunk ) ) {
363  DBGC ( trunk, "VLAN %s cannot create VLAN on non-trunk "
364  "device\n", trunk->name );
365  rc = -ENOTTY;
366  goto err_sanity;
367  }
368  if ( ! VLAN_TAG_IS_VALID ( tag ) ) {
369  DBGC ( trunk, "VLAN %s cannot create VLAN with invalid tag "
370  "%d\n", trunk->name, tag );
371  rc = -EINVAL;
372  goto err_sanity;
373  }
374  if ( ! VLAN_PRIORITY_IS_VALID ( priority ) ) {
375  DBGC ( trunk, "VLAN %s cannot create VLAN with invalid "
376  "priority %d\n", trunk->name, priority );
377  rc = -EINVAL;
378  goto err_sanity;
379  }
380 
381  /* Allocate and initialise structure */
382  netdev = alloc_etherdev ( sizeof ( *vlan ) );
383  if ( ! netdev ) {
384  rc = -ENOMEM;
385  goto err_alloc_etherdev;
386  }
388  netdev->dev = trunk->dev;
390  vlan = netdev->priv;
391  vlan->trunk = netdev_get ( trunk );
392  vlan->tag = tag;
393  vlan->priority = priority;
394 
395  /* Construct VLAN device name */
396  snprintf ( netdev->name, sizeof ( netdev->name ), "%s-%d",
397  trunk->name, vlan->tag );
398 
399  /* Mark device as not supporting interrupts, if applicable */
400  if ( ! netdev_irq_supported ( trunk ) )
402 
403  /* Register VLAN device */
404  if ( ( rc = register_netdev ( netdev ) ) != 0 ) {
405  DBGC ( netdev, "VLAN %s could not register: %s\n",
406  netdev->name, strerror ( rc ) );
407  goto err_register;
408  }
409 
410  /* Synchronise with trunk device */
411  vlan_sync ( netdev );
412 
413  DBGC ( netdev, "VLAN %s created with tag %d and priority %d\n",
414  netdev->name, vlan->tag, vlan->priority );
415 
416  return 0;
417 
419  err_register:
421  netdev_put ( netdev );
422  netdev_put ( trunk );
423  err_alloc_etherdev:
424  err_sanity:
425  return rc;
426 }
#define EINVAL
Invalid argument.
Definition: errno.h:429
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct net_device * trunk
Trunk network device.
Definition: vlan.c:52
static struct net_device_operations vlan_operations
VLAN device operations.
Definition: vlan.c:171
VLAN device private data.
Definition: vlan.c:50
#define DBGC(...)
Definition: compiler.h:505
unsigned int state
Current device state.
Definition: netdevice.h:396
#define VLAN_TAG_IS_VALID(tag)
Check VLAN tag is valid.
Definition: vlan.h:55
struct net_device * vlan_find(struct net_device *trunk, unsigned int tag)
Identify VLAN device.
Definition: vlan.c:209
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
Definition: netdevice.h:519
#define ENOMEM
Not enough space.
Definition: errno.h:535
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition: netdevice.h:576
#define VLAN_PRIORITY_IS_VALID(priority)
Check VLAN priority is valid.
Definition: vlan.h:63
void * priv
Driver private data.
Definition: netdevice.h:432
static void vlan_sync(struct net_device *netdev)
Synchronise VLAN device.
Definition: vlan.c:184
static struct net_device * netdev
Definition: gdbudp.c:52
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition: netdevice.c:942
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
int register_netdev(struct net_device *netdev)
Register network device.
Definition: netdevice.c:760
A network device.
Definition: netdevice.h:353
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
Definition: netdevice.h:532
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition: netdevice.h:565
#define ETH_ALEN
Definition: if_ether.h:9
struct device * dev
Underlying hardware device.
Definition: netdevice.h:365
unsigned int tag
VLAN tag.
Definition: vlan.c:54
int vlan_can_be_trunk(struct net_device *trunk)
Check if network device can be used as a VLAN trunk device.
Definition: vlan.c:330
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:363
#define ENOTTY
Inappropriate I/O control operation.
Definition: errno.h:595
uint16_t priority
Priotity.
Definition: stp.h:13
struct net_device * alloc_etherdev(size_t priv_size)
Allocate Ethernet device.
Definition: ethernet.c:265
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:383
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:388
unsigned int priority
Default priority.
Definition: vlan.c:56
uint64_t tag
Identity tag.
Definition: edd.h:31
#define NETDEV_IRQ_UNSUPPORTED
Network device interrupts are unsupported.
Definition: netdevice.h:453
uint8_t hw_addr[MAX_HW_ADDR_LEN]
Hardware address.
Definition: netdevice.h:382
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
static int netdev_irq_supported(struct net_device *netdev)
Check whether or not network device supports interrupts.
Definition: netdevice.h:673

References alloc_etherdev(), DBGC, net_device::dev, EINVAL, ENOMEM, ENOTTY, ETH_ALEN, net_device::hw_addr, net_device::ll_addr, memcpy(), net_device::name, netdev, netdev_get(), netdev_init(), netdev_irq_supported(), NETDEV_IRQ_UNSUPPORTED, netdev_nullify(), netdev_put(), NULL, priority, vlan_device::priority, net_device::priv, rc, register_netdev(), snprintf(), net_device::state, strerror(), tag, vlan_device::tag, vlan_device::trunk, unregister_netdev(), vlan_can_be_trunk(), vlan_find(), vlan_operations, VLAN_PRIORITY_IS_VALID, vlan_sync(), and VLAN_TAG_IS_VALID.

Referenced by efi_vlan_set(), fcoe_fip_rx_vlan(), vcreate_exec(), and vlan_probe().

◆ vlan_destroy()

int vlan_destroy ( struct net_device netdev)

Destroy VLAN device.

Parameters
netdevNetwork device
Return values
rcReturn status code

Definition at line 434 of file vlan.c.

434  {
435  struct vlan_device *vlan = netdev->priv;
436  struct net_device *trunk;
437 
438  /* Sanity check */
439  if ( netdev->op != &vlan_operations ) {
440  DBGC ( netdev, "VLAN %s cannot destroy non-VLAN device\n",
441  netdev->name );
442  return -ENOTTY;
443  }
444 
445  DBGC ( netdev, "VLAN %s destroyed\n", netdev->name );
446 
447  /* Remove VLAN device */
449  trunk = vlan->trunk;
451  netdev_put ( netdev );
452  netdev_put ( trunk );
453 
454  return 0;
455 }
struct net_device * trunk
Trunk network device.
Definition: vlan.c:52
static struct net_device_operations vlan_operations
VLAN device operations.
Definition: vlan.c:171
VLAN device private data.
Definition: vlan.c:50
#define DBGC(...)
Definition: compiler.h:505
struct net_device_operations * op
Network device operations.
Definition: netdevice.h:370
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition: netdevice.h:576
void * priv
Driver private data.
Definition: netdevice.h:432
static struct net_device * netdev
Definition: gdbudp.c:52
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition: netdevice.c:942
A network device.
Definition: netdevice.h:353
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
Definition: netdevice.h:532
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:363
#define ENOTTY
Inappropriate I/O control operation.
Definition: errno.h:595

References DBGC, ENOTTY, net_device::name, netdev, netdev_nullify(), netdev_put(), net_device::op, net_device::priv, vlan_device::trunk, unregister_netdev(), and vlan_operations.

Referenced by efi_vlan_remove(), vdestroy_exec(), and vlan_remove_first().

◆ vlan_auto()

void vlan_auto ( const void *  ll_addr,
unsigned int  tag 
)

Configure automatic VLAN device.

Parameters
ll_addrLink-layer address
tagVLAN tag

Definition at line 463 of file vlan.c.

463  {
464 
465  /* Record link-layer address and VLAN tag */
467  vlan_auto_tag = tag;
468 }
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static uint8_t vlan_auto_ll_addr[ETH_ALEN]
Automatic VLAN device link-layer address.
Definition: vlan.c:60
#define ETH_ALEN
Definition: if_ether.h:9
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:388
uint64_t tag
Identity tag.
Definition: edd.h:31
static unsigned int vlan_auto_tag
Automatic VLAN tag.
Definition: vlan.c:63

References ETH_ALEN, net_device::ll_addr, memcpy(), tag, vlan_auto_ll_addr, and vlan_auto_tag.

Referenced by efi_set_autoboot_ll_addr().

◆ vlan_probe()

static int vlan_probe ( struct net_device trunk,
void *priv  __unused 
)
static

Create automatic VLAN device.

Parameters
trunkTrunk network device
privPrivate data
Return values
rcReturn status code

Definition at line 477 of file vlan.c.

477  {
478  int rc;
479 
480  /* Do nothing unless an automatic VLAN exists */
481  if ( ! vlan_auto_tag )
482  return 0;
483 
484  /* Ignore non-trunk devices */
485  if ( ! vlan_can_be_trunk ( trunk ) )
486  return 0;
487 
488  /* Ignore non-matching link-layer addresses */
489  if ( memcmp ( trunk->ll_addr, vlan_auto_ll_addr, ETH_ALEN ) != 0 )
490  return 0;
491 
492  /* Create automatic VLAN device */
493  if ( ( rc = vlan_create ( trunk, vlan_auto_tag, 0 ) ) != 0 )
494  return rc;
495 
496  return 0;
497 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
int vlan_create(struct net_device *trunk, unsigned int tag, unsigned int priority)
Create VLAN device.
Definition: vlan.c:344
static uint8_t vlan_auto_ll_addr[ETH_ALEN]
Automatic VLAN device link-layer address.
Definition: vlan.c:60
#define ETH_ALEN
Definition: if_ether.h:9
int vlan_can_be_trunk(struct net_device *trunk)
Check if network device can be used as a VLAN trunk device.
Definition: vlan.c:330
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:388
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:115
static unsigned int vlan_auto_tag
Automatic VLAN tag.
Definition: vlan.c:63

References ETH_ALEN, net_device::ll_addr, memcmp(), rc, vlan_auto_ll_addr, vlan_auto_tag, vlan_can_be_trunk(), and vlan_create().

◆ vlan_notify()

static void vlan_notify ( struct net_device trunk,
void *priv  __unused 
)
static

Handle trunk network device link state change.

Parameters
trunkTrunk network device
privPrivate data

Definition at line 505 of file vlan.c.

505  {
506  struct net_device *netdev;
507  struct vlan_device *vlan;
508 
509  for_each_netdev ( netdev ) {
510  if ( netdev->op != &vlan_operations )
511  continue;
512  vlan = netdev->priv;
513  if ( vlan->trunk == trunk )
514  vlan_sync ( netdev );
515  }
516 }
struct net_device * trunk
Trunk network device.
Definition: vlan.c:52
static struct net_device_operations vlan_operations
VLAN device operations.
Definition: vlan.c:171
VLAN device private data.
Definition: vlan.c:50
struct net_device_operations * op
Network device operations.
Definition: netdevice.h:370
void * priv
Driver private data.
Definition: netdevice.h:432
static void vlan_sync(struct net_device *netdev)
Synchronise VLAN device.
Definition: vlan.c:184
static struct net_device * netdev
Definition: gdbudp.c:52
#define for_each_netdev(netdev)
Iterate over all network devices.
Definition: netdevice.h:547
A network device.
Definition: netdevice.h:353

References for_each_netdev, netdev, net_device::op, net_device::priv, vlan_device::trunk, vlan_operations, and vlan_sync().

◆ vlan_remove_first()

static int vlan_remove_first ( struct net_device trunk)
static

Destroy first VLAN device for a given trunk.

Parameters
trunkTrunk network device
Return values
foundA VLAN device was found

Definition at line 524 of file vlan.c.

524  {
525  struct net_device *netdev;
526  struct vlan_device *vlan;
527 
528  for_each_netdev ( netdev ) {
529  if ( netdev->op != &vlan_operations )
530  continue;
531  vlan = netdev->priv;
532  if ( vlan->trunk == trunk ) {
533  vlan_destroy ( netdev );
534  return 1;
535  }
536  }
537  return 0;
538 }
struct net_device * trunk
Trunk network device.
Definition: vlan.c:52
static struct net_device_operations vlan_operations
VLAN device operations.
Definition: vlan.c:171
VLAN device private data.
Definition: vlan.c:50
struct net_device_operations * op
Network device operations.
Definition: netdevice.h:370
void * priv
Driver private data.
Definition: netdevice.h:432
static struct net_device * netdev
Definition: gdbudp.c:52
#define for_each_netdev(netdev)
Iterate over all network devices.
Definition: netdevice.h:547
A network device.
Definition: netdevice.h:353
int vlan_destroy(struct net_device *netdev)
Destroy VLAN device.
Definition: vlan.c:434

References for_each_netdev, netdev, net_device::op, net_device::priv, vlan_device::trunk, vlan_destroy(), and vlan_operations.

Referenced by vlan_remove().

◆ vlan_remove()

static void vlan_remove ( struct net_device trunk,
void *priv  __unused 
)
static

Destroy all VLAN devices for a given trunk.

Parameters
trunkTrunk network device
privPrivate data

Definition at line 546 of file vlan.c.

546  {
547 
548  /* Remove all VLAN devices attached to this trunk, safe
549  * against arbitrary net device removal.
550  */
551  while ( vlan_remove_first ( trunk ) ) {}
552 }
struct net_device * trunk
Trunk network device.
Definition: vlan.c:52
static int vlan_remove_first(struct net_device *trunk)
Destroy first VLAN device for a given trunk.
Definition: vlan.c:524

References vlan_device::trunk, and vlan_remove_first().

◆ vlan_netdev_rx()

void vlan_netdev_rx ( struct net_device netdev,
unsigned int  tag,
struct io_buffer iobuf 
)

Add VLAN tag-stripped packet to receive queue.

Add VLAN tag-stripped packet to queue (when VLAN support is not present)

Parameters
netdevNetwork device
tagVLAN tag, or zero
iobufI/O buffer

Definition at line 569 of file vlan.c.

570  {
571  struct net_device *vlan;
572 
573  /* Identify VLAN device, if applicable */
574  if ( tag ) {
575  if ( ( vlan = vlan_find ( netdev, tag ) ) == NULL ) {
576  netdev_rx_err ( netdev, iobuf, -ENODEV );
577  return;
578  }
579  netdev = vlan;
580  }
581 
582  /* Hand off to network device */
583  netdev_rx ( netdev, iobuf );
584 }
void netdev_rx_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Discard received packet.
Definition: netdevice.c:587
struct net_device * vlan_find(struct net_device *trunk, unsigned int tag)
Identify VLAN device.
Definition: vlan.c:209
static struct net_device * netdev
Definition: gdbudp.c:52
A network device.
Definition: netdevice.h:353
#define ENODEV
No such device.
Definition: errno.h:510
void netdev_rx(struct net_device *netdev, struct io_buffer *iobuf)
Add packet to receive queue.
Definition: netdevice.c:549
uint64_t tag
Identity tag.
Definition: edd.h:31
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

References ENODEV, netdev, netdev_rx(), netdev_rx_err(), NULL, tag, and vlan_find().

◆ vlan_netdev_rx_err()

void vlan_netdev_rx_err ( struct net_device netdev,
unsigned int tag  ,
struct io_buffer iobuf,
int  rc 
)

Discard received VLAN tag-stripped packet.

Discard received VLAN tag-stripped packet (when VLAN support is not present)

Parameters
netdevNetwork device
tagVLAN tag, or zero
iobufI/O buffer, or NULL
rcPacket status code

Definition at line 594 of file vlan.c.

595  {
596  struct net_device *vlan;
597 
598  /* Identify VLAN device, if applicable */
599  if ( tag && ( ( vlan = vlan_find ( netdev, tag ) ) != NULL ) )
600  netdev = vlan;
601 
602  /* Hand off to network device */
603  netdev_rx_err ( netdev, iobuf, rc );
604 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void netdev_rx_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Discard received packet.
Definition: netdevice.c:587
struct net_device * vlan_find(struct net_device *trunk, unsigned int tag)
Identify VLAN device.
Definition: vlan.c:209
static struct net_device * netdev
Definition: gdbudp.c:52
A network device.
Definition: netdevice.h:353
uint64_t tag
Identity tag.
Definition: edd.h:31
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

References netdev, netdev_rx_err(), NULL, rc, tag, and vlan_find().

Variable Documentation

◆ __net_protocol

struct net_protocol vlan_protocol __net_protocol
Initial value:
= {
.name = "VLAN",
.net_proto = htons ( ETH_P_8021Q ),
.rx = vlan_rx,
}
static int vlan_rx(struct io_buffer *iobuf, struct net_device *trunk, const void *ll_dest, const void *ll_source, unsigned int flags __unused)
Process incoming VLAN packet.
Definition: vlan.c:233
#define htons(value)
Definition: byteswap.h:136
#define ETH_P_8021Q
Definition: if_ether.h:22

VLAN protocol.

AoE protocol.

Definition at line 47 of file vlan.c.

◆ vlan_auto_ll_addr

uint8_t vlan_auto_ll_addr[ETH_ALEN]
static

Automatic VLAN device link-layer address.

Definition at line 60 of file vlan.c.

Referenced by vlan_auto(), and vlan_probe().

◆ vlan_auto_tag

unsigned int vlan_auto_tag
static

Automatic VLAN tag.

Definition at line 63 of file vlan.c.

Referenced by vlan_auto(), and vlan_probe().

◆ vlan_operations

struct net_device_operations vlan_operations
static
Initial value:
= {
.open = vlan_open,
.close = vlan_close,
.transmit = vlan_transmit,
.poll = vlan_poll,
.irq = vlan_irq,
}
static void vlan_poll(struct net_device *netdev)
Poll VLAN device.
Definition: vlan.c:147
static void vlan_close(struct net_device *netdev)
Close VLAN device.
Definition: vlan.c:82
static void vlan_irq(struct net_device *netdev, int enable)
Enable/disable interrupts on VLAN device.
Definition: vlan.c:160
static int vlan_open(struct net_device *netdev)
Open VLAN device.
Definition: vlan.c:71
static int vlan_transmit(struct net_device *netdev, struct io_buffer *iobuf)
Transmit packet on VLAN device.
Definition: vlan.c:95

VLAN device operations.

Definition at line 171 of file vlan.c.

Referenced by vlan_can_be_trunk(), vlan_create(), vlan_destroy(), vlan_find(), vlan_notify(), vlan_remove_first(), and vlan_tci().

◆ __net_driver

struct net_driver vlan_driver __net_driver
Initial value:
= {
.name = "VLAN",
.probe = vlan_probe,
.notify = vlan_notify,
.remove = vlan_remove,
}
static void vlan_notify(struct net_device *trunk, void *priv __unused)
Handle trunk network device link state change.
Definition: vlan.c:505
static int vlan_probe(struct net_device *trunk, void *priv __unused)
Create automatic VLAN device.
Definition: vlan.c:477
static void vlan_remove(struct net_device *trunk, void *priv __unused)
Destroy all VLAN devices for a given trunk.
Definition: vlan.c:546

VLAN driver.

Definition at line 555 of file vlan.c.