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

◆ 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 70 of file vlan.c.

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

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

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

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 94 of file vlan.c.

95  {
96  struct vlan_device *vlan = netdev->priv;
97  struct net_device *trunk = vlan->trunk;
98  struct ll_protocol *ll_protocol;
99  struct vlan_header *vlanhdr;
100  uint8_t ll_dest_copy[ETH_ALEN];
101  uint8_t ll_source_copy[ETH_ALEN];
102  const void *ll_dest;
103  const void *ll_source;
105  unsigned int flags;
106  int rc;
107 
108  /* Strip link-layer header and preserve link-layer header fields */
110  if ( ( rc = ll_protocol->pull ( netdev, iobuf, &ll_dest, &ll_source,
111  &net_proto, &flags ) ) != 0 ) {
112  DBGC ( netdev, "VLAN %s could not parse link-layer header: "
113  "%s\n", netdev->name, strerror ( rc ) );
114  return rc;
115  }
116  memcpy ( ll_dest_copy, ll_dest, ETH_ALEN );
117  memcpy ( ll_source_copy, ll_source, ETH_ALEN );
118 
119  /* Construct VLAN header */
120  vlanhdr = iob_push ( iobuf, sizeof ( *vlanhdr ) );
121  vlanhdr->tci = htons ( VLAN_TCI ( vlan->tag, vlan->priority ) );
122  vlanhdr->net_proto = net_proto;
123 
124  /* Reclaim I/O buffer from VLAN device's TX queue */
125  list_del ( &iobuf->list );
126 
127  /* Transmit packet on trunk device */
128  if ( ( rc = net_tx ( iob_disown ( iobuf ), trunk, &vlan_protocol,
129  ll_dest_copy, ll_source_copy ) ) != 0 ) {
130  DBGC ( netdev, "VLAN %s could not transmit: %s\n",
131  netdev->name, strerror ( rc ) );
132  /* Cannot return an error status, since that would
133  * cause the I/O buffer to be double-freed.
134  */
135  return 0;
136  }
137 
138  return 0;
139 }
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:18
struct net_device * trunk
Trunk network device.
Definition: vlan.c:51
#define VLAN_TCI(tag, priority)
Construct VLAN tag control information.
Definition: vlan.h:46
uint16_t net_proto
Encapsulated protocol.
Definition: vlan.h:20
#define iob_push(iobuf, len)
Definition: iobuf.h:84
VLAN device private data.
Definition: vlan.c:49
#define DBGC(...)
Definition: compiler.h:505
A link-layer protocol.
Definition: netdevice.h:114
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:212
void * memcpy(void *dest, const void *src, size_t len) __nonnull
A VLAN header.
Definition: vlan.h:16
void * priv
Driver private data.
Definition: netdevice.h:431
static struct net_device * netdev
Definition: gdbudp.c:52
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
A network device.
Definition: netdevice.h:352
unsigned char uint8_t
Definition: stdint.h:10
#define ETH_ALEN
Definition: if_ether.h:8
unsigned int tag
VLAN tag.
Definition: vlan.c:53
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:141
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:40
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:1073
unsigned int priority
Default priority.
Definition: vlan.c:55
#define htons(value)
Definition: byteswap.h:135
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:372
uint8_t flags
Flags.
Definition: ena.h:18

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 146 of file vlan.c.

146  {
147  struct vlan_device *vlan = netdev->priv;
148 
149  /* Poll trunk device */
150  netdev_poll ( vlan->trunk );
151 }
struct net_device * trunk
Trunk network device.
Definition: vlan.c:51
VLAN device private data.
Definition: vlan.c:49
void * priv
Driver private data.
Definition: netdevice.h:431
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:612

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 159 of file vlan.c.

159  {
160  struct vlan_device *vlan = netdev->priv;
161 
162  /* Enable/disable interrupts on trunk device. This is not at
163  * all robust, but there is no sensible course of action
164  * available.
165  */
166  netdev_irq ( vlan->trunk, enable );
167 }
struct net_device * trunk
Trunk network device.
Definition: vlan.c:51
VLAN device private data.
Definition: vlan.c:49
void * priv
Driver private data.
Definition: netdevice.h:431
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:970

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 183 of file vlan.c.

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

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 208 of file vlan.c.

208  {
209  struct net_device *netdev;
210  struct vlan_device *vlan;
211 
212  for_each_netdev ( netdev ) {
213  if ( netdev->op != &vlan_operations )
214  continue;
215  vlan = netdev->priv;
216  if ( ( vlan->trunk == trunk ) && ( vlan->tag == tag ) )
217  return netdev;
218  }
219  return NULL;
220 }
struct net_device * trunk
Trunk network device.
Definition: vlan.c:51
static struct net_device_operations vlan_operations
VLAN device operations.
Definition: vlan.c:170
VLAN device private data.
Definition: vlan.c:49
struct net_device_operations * op
Network device operations.
Definition: netdevice.h:369
void * priv
Driver private data.
Definition: netdevice.h:431
static struct net_device * netdev
Definition: gdbudp.c:52
#define for_each_netdev(netdev)
Iterate over all network devices.
Definition: netdevice.h:543
A network device.
Definition: netdevice.h:352
unsigned int tag
VLAN tag.
Definition: vlan.c:53
uint64_t tag
Identity tag.
Definition: edd.h:30
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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 232 of file vlan.c.

234  {
235  struct vlan_header *vlanhdr = iobuf->data;
236  struct net_device *netdev;
237  struct ll_protocol *ll_protocol;
238  uint8_t ll_dest_copy[ETH_ALEN];
239  uint8_t ll_source_copy[ETH_ALEN];
240  uint16_t tag;
241  int rc;
242 
243  /* Sanity check */
244  if ( iob_len ( iobuf ) < sizeof ( *vlanhdr ) ) {
245  DBGC ( trunk, "VLAN %s received underlength packet (%zd "
246  "bytes)\n", trunk->name, iob_len ( iobuf ) );
247  rc = -EINVAL;
248  goto err_sanity;
249  }
250 
251  /* Identify VLAN device */
252  tag = VLAN_TAG ( ntohs ( vlanhdr->tci ) );
253  netdev = vlan_find ( trunk, tag );
254  if ( ! netdev ) {
255  DBGC2 ( trunk, "VLAN %s received packet for unknown VLAN "
256  "%d\n", trunk->name, tag );
257  rc = -EPIPE;
258  goto err_no_vlan;
259  }
260 
261  /* Strip VLAN header and preserve original link-layer header fields */
262  iob_pull ( iobuf, sizeof ( *vlanhdr ) );
263  ll_protocol = trunk->ll_protocol;
264  memcpy ( ll_dest_copy, ll_dest, ETH_ALEN );
265  memcpy ( ll_source_copy, ll_source, ETH_ALEN );
266 
267  /* Reconstruct link-layer header for VLAN device */
269  if ( ( rc = ll_protocol->push ( netdev, iobuf, ll_dest_copy,
270  ll_source_copy,
271  vlanhdr->net_proto ) ) != 0 ) {
272  DBGC ( netdev, "VLAN %s could not reconstruct link-layer "
273  "header: %s\n", netdev->name, strerror ( rc ) );
274  goto err_ll_push;
275  }
276 
277  /* Enqueue packet on VLAN device */
278  netdev_rx ( netdev, iob_disown ( iobuf ) );
279  return 0;
280 
281  err_ll_push:
282  err_no_vlan:
283  err_sanity:
284  free_iob ( iobuf );
285  return rc;
286 }
#define iob_pull(iobuf, len)
Definition: iobuf.h:102
#define VLAN_TAG(tci)
Extract VLAN tag from tag control information.
Definition: vlan.h:29
#define EINVAL
Invalid argument.
Definition: errno.h:428
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:18
uint16_t net_proto
Encapsulated protocol.
Definition: vlan.h:20
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
#define EPIPE
Broken pipe.
Definition: errno.h:619
#define DBGC(...)
Definition: compiler.h:505
#define ntohs(value)
Definition: byteswap.h:136
A link-layer protocol.
Definition: netdevice.h:114
struct net_device * vlan_find(struct net_device *trunk, unsigned int tag)
Identify VLAN device.
Definition: vlan.c:208
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:127
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:212
void * memcpy(void *dest, const void *src, size_t len) __nonnull
A VLAN header.
Definition: vlan.h:16
static struct net_device * netdev
Definition: gdbudp.c:52
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155
A network device.
Definition: netdevice.h:352
unsigned char uint8_t
Definition: stdint.h:10
#define ETH_ALEN
Definition: if_ether.h:8
void netdev_rx(struct net_device *netdev, struct io_buffer *iobuf)
Add packet to receive queue.
Definition: netdevice.c:548
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
#define DBGC2(...)
Definition: compiler.h:522
void * data
Start of data.
Definition: iobuf.h:48
uint64_t tag
Identity tag.
Definition: edd.h:30
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:372

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 301 of file vlan.c.

301  {
302  struct vlan_device *vlan;
303 
304  if ( netdev->op == &vlan_operations ) {
305  vlan = netdev->priv;
306  return ( VLAN_TCI ( vlan->tag, vlan->priority ) );
307  } else {
308  return 0;
309  }
310 }
static struct net_device_operations vlan_operations
VLAN device operations.
Definition: vlan.c:170
#define VLAN_TCI(tag, priority)
Construct VLAN tag control information.
Definition: vlan.h:46
VLAN device private data.
Definition: vlan.c:49
struct net_device_operations * op
Network device operations.
Definition: netdevice.h:369
void * priv
Driver private data.
Definition: netdevice.h:431
static struct net_device * netdev
Definition: gdbudp.c:52
unsigned int tag
VLAN tag.
Definition: vlan.c:53
unsigned int priority
Default priority.
Definition: vlan.c:55

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 329 of file vlan.c.

329  {
330 
331  return ( ( trunk->ll_protocol->ll_addr_len == ETH_ALEN ) &&
332  ( trunk->op != &vlan_operations ) );
333 }
struct net_device * trunk
Trunk network device.
Definition: vlan.c:51
uint8_t ll_addr_len
Link-layer address length.
Definition: netdevice.h:198
static struct net_device_operations vlan_operations
VLAN device operations.
Definition: vlan.c:170
struct net_device_operations * op
Network device operations.
Definition: netdevice.h:369
#define ETH_ALEN
Definition: if_ether.h:8
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:372

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 343 of file vlan.c.

344  {
345  struct net_device *netdev;
346  struct vlan_device *vlan;
347  int rc;
348 
349  /* If VLAN already exists, just update the priority */
350  if ( ( netdev = vlan_find ( trunk, tag ) ) != NULL ) {
351  vlan = netdev->priv;
352  if ( priority != vlan->priority ) {
353  DBGC ( netdev, "VLAN %s priority changed from %d to "
354  "%d\n", netdev->name, vlan->priority, priority );
355  }
356  vlan->priority = priority;
357  return 0;
358  }
359 
360  /* Sanity checks */
361  if ( ! vlan_can_be_trunk ( trunk ) ) {
362  DBGC ( trunk, "VLAN %s cannot create VLAN on non-trunk "
363  "device\n", trunk->name );
364  rc = -ENOTTY;
365  goto err_sanity;
366  }
367  if ( ! VLAN_TAG_IS_VALID ( tag ) ) {
368  DBGC ( trunk, "VLAN %s cannot create VLAN with invalid tag "
369  "%d\n", trunk->name, tag );
370  rc = -EINVAL;
371  goto err_sanity;
372  }
373  if ( ! VLAN_PRIORITY_IS_VALID ( priority ) ) {
374  DBGC ( trunk, "VLAN %s cannot create VLAN with invalid "
375  "priority %d\n", trunk->name, priority );
376  rc = -EINVAL;
377  goto err_sanity;
378  }
379 
380  /* Allocate and initialise structure */
381  netdev = alloc_etherdev ( sizeof ( *vlan ) );
382  if ( ! netdev ) {
383  rc = -ENOMEM;
384  goto err_alloc_etherdev;
385  }
387  netdev->dev = trunk->dev;
389  vlan = netdev->priv;
390  vlan->trunk = netdev_get ( trunk );
391  vlan->tag = tag;
392  vlan->priority = priority;
393 
394  /* Construct VLAN device name */
395  snprintf ( netdev->name, sizeof ( netdev->name ), "%s-%d",
396  trunk->name, vlan->tag );
397 
398  /* Mark device as not supporting interrupts, if applicable */
399  if ( ! netdev_irq_supported ( trunk ) )
401 
402  /* Register VLAN device */
403  if ( ( rc = register_netdev ( netdev ) ) != 0 ) {
404  DBGC ( netdev, "VLAN %s could not register: %s\n",
405  netdev->name, strerror ( rc ) );
406  goto err_register;
407  }
408 
409  /* Synchronise with trunk device */
410  vlan_sync ( netdev );
411 
412  DBGC ( netdev, "VLAN %s created with tag %d and priority %d\n",
413  netdev->name, vlan->tag, vlan->priority );
414 
415  return 0;
416 
418  err_register:
420  netdev_put ( netdev );
421  netdev_put ( trunk );
422  err_alloc_etherdev:
423  err_sanity:
424  return rc;
425 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct net_device * trunk
Trunk network device.
Definition: vlan.c:51
static struct net_device_operations vlan_operations
VLAN device operations.
Definition: vlan.c:170
VLAN device private data.
Definition: vlan.c:49
#define DBGC(...)
Definition: compiler.h:505
unsigned int state
Current device state.
Definition: netdevice.h:395
#define VLAN_TAG_IS_VALID(tag)
Check VLAN tag is valid.
Definition: vlan.h:54
struct net_device * vlan_find(struct net_device *trunk, unsigned int tag)
Identify VLAN device.
Definition: vlan.c:208
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
Definition: netdevice.h:515
#define ENOMEM
Not enough space.
Definition: errno.h:534
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:572
#define VLAN_PRIORITY_IS_VALID(priority)
Check VLAN priority is valid.
Definition: vlan.h:62
void * priv
Driver private data.
Definition: netdevice.h:431
static void vlan_sync(struct net_device *netdev)
Synchronise VLAN device.
Definition: vlan.c:183
static struct net_device * netdev
Definition: gdbudp.c:52
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition: netdevice.c:941
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
int register_netdev(struct net_device *netdev)
Register network device.
Definition: netdevice.c:759
A network device.
Definition: netdevice.h:352
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
Definition: netdevice.h:528
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition: netdevice.h:561
#define ETH_ALEN
Definition: if_ether.h:8
struct device * dev
Underlying hardware device.
Definition: netdevice.h:364
unsigned int tag
VLAN tag.
Definition: vlan.c:53
int vlan_can_be_trunk(struct net_device *trunk)
Check if network device can be used as a VLAN trunk device.
Definition: vlan.c:329
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
#define ENOTTY
Inappropriate I/O control operation.
Definition: errno.h:594
uint16_t priority
Priotity.
Definition: stp.h:12
struct net_device * alloc_etherdev(size_t priv_size)
Allocate Ethernet device.
Definition: ethernet.c:264
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:387
unsigned int priority
Default priority.
Definition: vlan.c:55
uint64_t tag
Identity tag.
Definition: edd.h:30
#define NETDEV_IRQ_UNSUPPORTED
Network device interrupts are unsupported.
Definition: netdevice.h:452
uint8_t hw_addr[MAX_HW_ADDR_LEN]
Hardware address.
Definition: netdevice.h:381
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
static int netdev_irq_supported(struct net_device *netdev)
Check whether or not network device supports interrupts.
Definition: netdevice.h:669

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 433 of file vlan.c.

433  {
434  struct vlan_device *vlan = netdev->priv;
435  struct net_device *trunk;
436 
437  /* Sanity check */
438  if ( netdev->op != &vlan_operations ) {
439  DBGC ( netdev, "VLAN %s cannot destroy non-VLAN device\n",
440  netdev->name );
441  return -ENOTTY;
442  }
443 
444  DBGC ( netdev, "VLAN %s destroyed\n", netdev->name );
445 
446  /* Remove VLAN device */
448  trunk = vlan->trunk;
450  netdev_put ( netdev );
451  netdev_put ( trunk );
452 
453  return 0;
454 }
struct net_device * trunk
Trunk network device.
Definition: vlan.c:51
static struct net_device_operations vlan_operations
VLAN device operations.
Definition: vlan.c:170
VLAN device private data.
Definition: vlan.c:49
#define DBGC(...)
Definition: compiler.h:505
struct net_device_operations * op
Network device operations.
Definition: netdevice.h:369
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition: netdevice.h:572
void * priv
Driver private data.
Definition: netdevice.h:431
static struct net_device * netdev
Definition: gdbudp.c:52
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition: netdevice.c:941
A network device.
Definition: netdevice.h:352
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
Definition: netdevice.h:528
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
#define ENOTTY
Inappropriate I/O control operation.
Definition: errno.h:594

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 462 of file vlan.c.

462  {
463 
464  /* Record link-layer address and VLAN tag */
466  vlan_auto_tag = tag;
467 }
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:59
#define ETH_ALEN
Definition: if_ether.h:8
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:387
uint64_t tag
Identity tag.
Definition: edd.h:30
static unsigned int vlan_auto_tag
Automatic VLAN tag.
Definition: vlan.c:62

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 476 of file vlan.c.

476  {
477  int rc;
478 
479  /* Do nothing unless an automatic VLAN exists */
480  if ( ! vlan_auto_tag )
481  return 0;
482 
483  /* Ignore non-trunk devices */
484  if ( ! vlan_can_be_trunk ( trunk ) )
485  return 0;
486 
487  /* Ignore non-matching link-layer addresses */
488  if ( memcmp ( trunk->ll_addr, vlan_auto_ll_addr, ETH_ALEN ) != 0 )
489  return 0;
490 
491  /* Create automatic VLAN device */
492  if ( ( rc = vlan_create ( trunk, vlan_auto_tag, 0 ) ) != 0 )
493  return rc;
494 
495  return 0;
496 }
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:343
static uint8_t vlan_auto_ll_addr[ETH_ALEN]
Automatic VLAN device link-layer address.
Definition: vlan.c:59
#define ETH_ALEN
Definition: if_ether.h:8
int vlan_can_be_trunk(struct net_device *trunk)
Check if network device can be used as a VLAN trunk device.
Definition: vlan.c:329
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:387
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
static unsigned int vlan_auto_tag
Automatic VLAN tag.
Definition: vlan.c:62

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 504 of file vlan.c.

504  {
505  struct net_device *netdev;
506  struct vlan_device *vlan;
507 
508  for_each_netdev ( netdev ) {
509  if ( netdev->op != &vlan_operations )
510  continue;
511  vlan = netdev->priv;
512  if ( vlan->trunk == trunk )
513  vlan_sync ( netdev );
514  }
515 }
struct net_device * trunk
Trunk network device.
Definition: vlan.c:51
static struct net_device_operations vlan_operations
VLAN device operations.
Definition: vlan.c:170
VLAN device private data.
Definition: vlan.c:49
struct net_device_operations * op
Network device operations.
Definition: netdevice.h:369
void * priv
Driver private data.
Definition: netdevice.h:431
static void vlan_sync(struct net_device *netdev)
Synchronise VLAN device.
Definition: vlan.c:183
static struct net_device * netdev
Definition: gdbudp.c:52
#define for_each_netdev(netdev)
Iterate over all network devices.
Definition: netdevice.h:543
A network device.
Definition: netdevice.h:352

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 523 of file vlan.c.

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

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 545 of file vlan.c.

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

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 568 of file vlan.c.

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

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 593 of file vlan.c.

594  {
595  struct net_device *vlan;
596 
597  /* Identify VLAN device, if applicable */
598  if ( tag && ( ( vlan = vlan_find ( netdev, tag ) ) != NULL ) )
599  netdev = vlan;
600 
601  /* Hand off to network device */
602  netdev_rx_err ( netdev, iobuf, rc );
603 }
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:586
struct net_device * vlan_find(struct net_device *trunk, unsigned int tag)
Identify VLAN device.
Definition: vlan.c:208
static struct net_device * netdev
Definition: gdbudp.c:52
A network device.
Definition: netdevice.h:352
uint64_t tag
Identity tag.
Definition: edd.h:30
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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:232
#define htons(value)
Definition: byteswap.h:135
#define ETH_P_8021Q
Definition: if_ether.h:21

VLAN protocol.

AoE protocol.

Definition at line 46 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 59 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 62 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:146
static void vlan_close(struct net_device *netdev)
Close VLAN device.
Definition: vlan.c:81
static void vlan_irq(struct net_device *netdev, int enable)
Enable/disable interrupts on VLAN device.
Definition: vlan.c:159
static int vlan_open(struct net_device *netdev)
Open VLAN device.
Definition: vlan.c:70
static int vlan_transmit(struct net_device *netdev, struct io_buffer *iobuf)
Transmit packet on VLAN device.
Definition: vlan.c:94

VLAN device operations.

Definition at line 170 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:504
static int vlan_probe(struct net_device *trunk, void *priv __unused)
Create automatic VLAN device.
Definition: vlan.c:476
static void vlan_remove(struct net_device *trunk, void *priv __unused)
Destroy all VLAN devices for a given trunk.
Definition: vlan.c:545

VLAN driver.

Definition at line 554 of file vlan.c.