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...
 
static 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_tag (struct net_device *netdev)
 Get the VLAN tag. 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...
 
static void vlan_notify (struct net_device *trunk)
 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)
 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 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 64 of file vlan.c.

64  {
65  struct vlan_device *vlan = netdev->priv;
66 
67  return netdev_open ( vlan->trunk );
68 }
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:425
static struct net_device * netdev
Definition: gdbudp.c:52
int netdev_open(struct net_device *netdev)
Open network device.
Definition: netdevice.c:767

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

75  {
76  struct vlan_device *vlan = netdev->priv;
77 
78  netdev_close ( vlan->trunk );
79 }
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:425
static struct net_device * netdev
Definition: gdbudp.c:52
void netdev_close(struct net_device *netdev)
Close network device.
Definition: netdevice.c:801

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

89  {
90  struct vlan_device *vlan = netdev->priv;
91  struct net_device *trunk = vlan->trunk;
92  struct ll_protocol *ll_protocol;
93  struct vlan_header *vlanhdr;
94  uint8_t ll_dest_copy[ETH_ALEN];
95  uint8_t ll_source_copy[ETH_ALEN];
96  const void *ll_dest;
97  const void *ll_source;
99  unsigned int flags;
100  int rc;
101 
102  /* Strip link-layer header and preserve link-layer header fields */
104  if ( ( rc = ll_protocol->pull ( netdev, iobuf, &ll_dest, &ll_source,
105  &net_proto, &flags ) ) != 0 ) {
106  DBGC ( netdev, "VLAN %s could not parse link-layer header: "
107  "%s\n", netdev->name, strerror ( rc ) );
108  return rc;
109  }
110  memcpy ( ll_dest_copy, ll_dest, ETH_ALEN );
111  memcpy ( ll_source_copy, ll_source, ETH_ALEN );
112 
113  /* Construct VLAN header */
114  vlanhdr = iob_push ( iobuf, sizeof ( *vlanhdr ) );
115  vlanhdr->tci = htons ( VLAN_TCI ( vlan->tag, vlan->priority ) );
116  vlanhdr->net_proto = net_proto;
117 
118  /* Reclaim I/O buffer from VLAN device's TX queue */
119  list_del ( &iobuf->list );
120 
121  /* Transmit packet on trunk device */
122  if ( ( rc = net_tx ( iob_disown ( iobuf ), trunk, &vlan_protocol,
123  ll_dest_copy, ll_source_copy ) ) != 0 ) {
124  DBGC ( netdev, "VLAN %s could not transmit: %s\n",
125  netdev->name, strerror ( rc ) );
126  /* Cannot return an error status, since that would
127  * cause the I/O buffer to be double-freed.
128  */
129  return 0;
130  }
131 
132  return 0;
133 }
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:80
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:208
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:425
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:348
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:358
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:39
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:999
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:366
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 140 of file vlan.c.

140  {
141  struct vlan_device *vlan = netdev->priv;
142 
143  /* Poll trunk device */
144  netdev_poll ( vlan->trunk );
145 }
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:425
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:523

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

153  {
154  struct vlan_device *vlan = netdev->priv;
155 
156  /* Enable/disable interrupts on trunk device. This is not at
157  * all robust, but there is no sensible course of action
158  * available.
159  */
160  netdev_irq ( vlan->trunk, enable );
161 }
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:425
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:875

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

177  {
178  struct vlan_device *vlan = netdev->priv;
179  struct net_device *trunk = vlan->trunk;
180 
181  /* Synchronise link status */
182  if ( netdev->link_rc != trunk->link_rc )
183  netdev_link_err ( netdev, trunk->link_rc );
184 
185  /* Synchronise open/closed status */
186  if ( netdev_is_open ( trunk ) ) {
187  if ( ! netdev_is_open ( netdev ) )
188  netdev_open ( netdev );
189  } else {
190  if ( netdev_is_open ( netdev ) )
191  netdev_close ( netdev );
192  }
193 }
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:652
int link_rc
Link status code.
Definition: netdevice.h:395
void * priv
Driver private data.
Definition: netdevice.h:425
static struct net_device * netdev
Definition: gdbudp.c:52
A network device.
Definition: netdevice.h:348
void netdev_link_err(struct net_device *netdev, int rc)
Mark network device as having a specific link state.
Definition: netdevice.c:163
void netdev_close(struct net_device *netdev)
Close network device.
Definition: netdevice.c:801
int netdev_open(struct net_device *netdev)
Open network device.
Definition: netdevice.c:767

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

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

Identify VLAN device.

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

Definition at line 202 of file vlan.c.

203  {
204  struct net_device *netdev;
205  struct vlan_device *vlan;
206 
207  for_each_netdev ( netdev ) {
208  if ( netdev->op != &vlan_operations )
209  continue;
210  vlan = netdev->priv;
211  if ( ( vlan->trunk == trunk ) && ( vlan->tag == tag ) )
212  return netdev;
213  }
214  return NULL;
215 }
struct net_device * trunk
Trunk network device.
Definition: vlan.c:51
static struct net_device_operations vlan_operations
VLAN device operations.
Definition: vlan.c:164
VLAN device private data.
Definition: vlan.c:49
struct net_device_operations * op
Network device operations.
Definition: netdevice.h:363
void * priv
Driver private data.
Definition: netdevice.h:425
static struct net_device * netdev
Definition: gdbudp.c:52
#define for_each_netdev(netdev)
Iterate over all network devices.
Definition: netdevice.h:526
A network device.
Definition: netdevice.h:348
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:362

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

Referenced by 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 227 of file vlan.c.

229  {
230  struct vlan_header *vlanhdr = iobuf->data;
231  struct net_device *netdev;
232  struct ll_protocol *ll_protocol;
233  uint8_t ll_dest_copy[ETH_ALEN];
234  uint8_t ll_source_copy[ETH_ALEN];
235  uint16_t tag;
236  int rc;
237 
238  /* Sanity check */
239  if ( iob_len ( iobuf ) < sizeof ( *vlanhdr ) ) {
240  DBGC ( trunk, "VLAN %s received underlength packet (%zd "
241  "bytes)\n", trunk->name, iob_len ( iobuf ) );
242  rc = -EINVAL;
243  goto err_sanity;
244  }
245 
246  /* Identify VLAN device */
247  tag = VLAN_TAG ( ntohs ( vlanhdr->tci ) );
248  netdev = vlan_find ( trunk, tag );
249  if ( ! netdev ) {
250  DBGC2 ( trunk, "VLAN %s received packet for unknown VLAN "
251  "%d\n", trunk->name, tag );
252  rc = -EPIPE;
253  goto err_no_vlan;
254  }
255 
256  /* Strip VLAN header and preserve original link-layer header fields */
257  iob_pull ( iobuf, sizeof ( *vlanhdr ) );
258  ll_protocol = trunk->ll_protocol;
259  memcpy ( ll_dest_copy, ll_dest, ETH_ALEN );
260  memcpy ( ll_source_copy, ll_source, ETH_ALEN );
261 
262  /* Reconstruct link-layer header for VLAN device */
264  if ( ( rc = ll_protocol->push ( netdev, iobuf, ll_dest_copy,
265  ll_source_copy,
266  vlanhdr->net_proto ) ) != 0 ) {
267  DBGC ( netdev, "VLAN %s could not reconstruct link-layer "
268  "header: %s\n", netdev->name, strerror ( rc ) );
269  goto err_ll_push;
270  }
271 
272  /* Enqueue packet on VLAN device */
273  netdev_rx ( netdev, iob_disown ( iobuf ) );
274  return 0;
275 
276  err_ll_push:
277  err_no_vlan:
278  err_sanity:
279  free_iob ( iobuf );
280  return rc;
281 }
#define iob_pull(iobuf, len)
Definition: iobuf.h:98
#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:145
#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
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:208
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:151
A network device.
Definition: netdevice.h:348
unsigned char uint8_t
Definition: stdint.h:10
static struct net_device * vlan_find(struct net_device *trunk, unsigned int tag)
Identify VLAN device.
Definition: vlan.c:202
#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:470
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:358
#define DBGC2(...)
Definition: compiler.h:522
void * data
Start of data.
Definition: iobuf.h:44
uint64_t tag
Identity tag.
Definition: edd.h:30
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:366

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

unsigned int vlan_tag ( struct net_device netdev)

Get the VLAN tag.

Parameters
netdevNetwork device
Return values
tagVLAN tag, or 0 if device is not a VLAN device

Definition at line 296 of file vlan.c.

296  {
297  struct vlan_device *vlan;
298 
299  if ( netdev->op == &vlan_operations ) {
300  vlan = netdev->priv;
301  return vlan->tag;
302  } else {
303  return 0;
304  }
305 }
static struct net_device_operations vlan_operations
VLAN device operations.
Definition: vlan.c:164
VLAN device private data.
Definition: vlan.c:49
struct net_device_operations * op
Network device operations.
Definition: netdevice.h:363
void * priv
Driver private data.
Definition: netdevice.h:425
static struct net_device * netdev
Definition: gdbudp.c:52
unsigned int tag
VLAN tag.
Definition: vlan.c:53

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

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

324  {
325 
326  return ( ( trunk->ll_protocol->ll_addr_len == ETH_ALEN ) &&
327  ( trunk->op != &vlan_operations ) );
328 }
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:164
struct net_device_operations * op
Network device operations.
Definition: netdevice.h:363
#define ETH_ALEN
Definition: if_ether.h:8
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:366

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(), and vlan_create().

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

339  {
340  struct net_device *netdev;
341  struct vlan_device *vlan;
342  int rc;
343 
344  /* If VLAN already exists, just update the priority */
345  if ( ( netdev = vlan_find ( trunk, tag ) ) != NULL ) {
346  vlan = netdev->priv;
347  if ( priority != vlan->priority ) {
348  DBGC ( netdev, "VLAN %s priority changed from %d to "
349  "%d\n", netdev->name, vlan->priority, priority );
350  }
351  vlan->priority = priority;
352  return 0;
353  }
354 
355  /* Sanity checks */
356  if ( ! vlan_can_be_trunk ( trunk ) ) {
357  DBGC ( trunk, "VLAN %s cannot create VLAN on non-trunk "
358  "device\n", trunk->name );
359  rc = -ENOTTY;
360  goto err_sanity;
361  }
362  if ( ! VLAN_TAG_IS_VALID ( tag ) ) {
363  DBGC ( trunk, "VLAN %s cannot create VLAN with invalid tag "
364  "%d\n", trunk->name, tag );
365  rc = -EINVAL;
366  goto err_sanity;
367  }
368  if ( ! VLAN_PRIORITY_IS_VALID ( priority ) ) {
369  DBGC ( trunk, "VLAN %s cannot create VLAN with invalid "
370  "priority %d\n", trunk->name, priority );
371  rc = -EINVAL;
372  goto err_sanity;
373  }
374 
375  /* Allocate and initialise structure */
376  netdev = alloc_etherdev ( sizeof ( *vlan ) );
377  if ( ! netdev ) {
378  rc = -ENOMEM;
379  goto err_alloc_etherdev;
380  }
382  netdev->dev = trunk->dev;
384  vlan = netdev->priv;
385  vlan->trunk = netdev_get ( trunk );
386  vlan->tag = tag;
387  vlan->priority = priority;
388 
389  /* Construct VLAN device name */
390  snprintf ( netdev->name, sizeof ( netdev->name ), "%s-%d",
391  trunk->name, vlan->tag );
392 
393  /* Mark device as not supporting interrupts, if applicable */
394  if ( ! netdev_irq_supported ( trunk ) )
396 
397  /* Register VLAN device */
398  if ( ( rc = register_netdev ( netdev ) ) != 0 ) {
399  DBGC ( netdev, "VLAN %s could not register: %s\n",
400  netdev->name, strerror ( rc ) );
401  goto err_register;
402  }
403 
404  /* Synchronise with trunk device */
405  vlan_sync ( netdev );
406 
407  DBGC ( netdev, "VLAN %s created with tag %d and priority %d\n",
408  netdev->name, vlan->tag, vlan->priority );
409 
410  return 0;
411 
413  err_register:
415  netdev_put ( netdev );
416  netdev_put ( trunk );
417  err_alloc_etherdev:
418  err_sanity:
419  return rc;
420 }
#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:164
VLAN device private data.
Definition: vlan.c:49
#define DBGC(...)
Definition: compiler.h:505
unsigned int state
Current device state.
Definition: netdevice.h:389
#define VLAN_TAG_IS_VALID(tag)
Check VLAN tag is valid.
Definition: vlan.h:54
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
Definition: netdevice.h:498
#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:555
#define VLAN_PRIORITY_IS_VALID(priority)
Check VLAN priority is valid.
Definition: vlan.h:62
void * priv
Driver private data.
Definition: netdevice.h:425
static void vlan_sync(struct net_device *netdev)
Synchronise VLAN device.
Definition: vlan.c:177
static struct net_device * netdev
Definition: gdbudp.c:52
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition: netdevice.c:844
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:667
A network device.
Definition: netdevice.h:348
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
Definition: netdevice.h:511
static struct net_device * vlan_find(struct net_device *trunk, unsigned int tag)
Identify VLAN device.
Definition: vlan.c:202
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition: netdevice.h:544
#define ETH_ALEN
Definition: if_ether.h:8
struct device * dev
Underlying hardware device.
Definition: netdevice.h:360
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:324
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:358
#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:381
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:446
uint8_t hw_addr[MAX_HW_ADDR_LEN]
Hardware address.
Definition: netdevice.h:375
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
static int netdev_irq_supported(struct net_device *netdev)
Check whether or not network device supports interrupts.
Definition: netdevice.h:663

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 fcoe_fip_rx_vlan(), and vcreate_exec().

◆ vlan_destroy()

int vlan_destroy ( struct net_device netdev)

Destroy VLAN device.

Parameters
netdevNetwork device
Return values
rcReturn status code

Definition at line 428 of file vlan.c.

428  {
429  struct vlan_device *vlan = netdev->priv;
430  struct net_device *trunk;
431 
432  /* Sanity check */
433  if ( netdev->op != &vlan_operations ) {
434  DBGC ( netdev, "VLAN %s cannot destroy non-VLAN device\n",
435  netdev->name );
436  return -ENOTTY;
437  }
438 
439  DBGC ( netdev, "VLAN %s destroyed\n", netdev->name );
440 
441  /* Remove VLAN device */
443  trunk = vlan->trunk;
445  netdev_put ( netdev );
446  netdev_put ( trunk );
447 
448  return 0;
449 }
struct net_device * trunk
Trunk network device.
Definition: vlan.c:51
static struct net_device_operations vlan_operations
VLAN device operations.
Definition: vlan.c:164
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:363
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition: netdevice.h:555
void * priv
Driver private data.
Definition: netdevice.h:425
static struct net_device * netdev
Definition: gdbudp.c:52
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition: netdevice.c:844
A network device.
Definition: netdevice.h:348
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
Definition: netdevice.h:511
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:358
#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 vdestroy_exec(), and vlan_remove_first().

◆ vlan_notify()

static void vlan_notify ( struct net_device trunk)
static

Handle trunk network device link state change.

Parameters
trunkTrunk network device

Definition at line 456 of file vlan.c.

456  {
457  struct net_device *netdev;
458  struct vlan_device *vlan;
459 
460  for_each_netdev ( netdev ) {
461  if ( netdev->op != &vlan_operations )
462  continue;
463  vlan = netdev->priv;
464  if ( vlan->trunk == trunk )
465  vlan_sync ( netdev );
466  }
467 }
struct net_device * trunk
Trunk network device.
Definition: vlan.c:51
static struct net_device_operations vlan_operations
VLAN device operations.
Definition: vlan.c:164
VLAN device private data.
Definition: vlan.c:49
struct net_device_operations * op
Network device operations.
Definition: netdevice.h:363
void * priv
Driver private data.
Definition: netdevice.h:425
static void vlan_sync(struct net_device *netdev)
Synchronise VLAN device.
Definition: vlan.c:177
static struct net_device * netdev
Definition: gdbudp.c:52
#define for_each_netdev(netdev)
Iterate over all network devices.
Definition: netdevice.h:526
A network device.
Definition: netdevice.h:348

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

475  {
476  struct net_device *netdev;
477  struct vlan_device *vlan;
478 
479  for_each_netdev ( netdev ) {
480  if ( netdev->op != &vlan_operations )
481  continue;
482  vlan = netdev->priv;
483  if ( vlan->trunk == trunk ) {
484  vlan_destroy ( netdev );
485  return 1;
486  }
487  }
488  return 0;
489 }
struct net_device * trunk
Trunk network device.
Definition: vlan.c:51
static struct net_device_operations vlan_operations
VLAN device operations.
Definition: vlan.c:164
VLAN device private data.
Definition: vlan.c:49
struct net_device_operations * op
Network device operations.
Definition: netdevice.h:363
void * priv
Driver private data.
Definition: netdevice.h:425
static struct net_device * netdev
Definition: gdbudp.c:52
#define for_each_netdev(netdev)
Iterate over all network devices.
Definition: netdevice.h:526
A network device.
Definition: netdevice.h:348
int vlan_destroy(struct net_device *netdev)
Destroy VLAN device.
Definition: vlan.c:428

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

Destroy all VLAN devices for a given trunk.

Parameters
trunkTrunk network device

Definition at line 496 of file vlan.c.

496  {
497 
498  /* Remove all VLAN devices attached to this trunk, safe
499  * against arbitrary net device removal.
500  */
501  while ( vlan_remove_first ( trunk ) ) {}
502 }
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:475

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

519  {
520  struct net_device *vlan;
521 
522  /* Identify VLAN device, if applicable */
523  if ( tag ) {
524  if ( ( vlan = vlan_find ( netdev, tag ) ) == NULL ) {
525  netdev_rx_err ( netdev, iobuf, -ENODEV );
526  return;
527  }
528  netdev = vlan;
529  }
530 
531  /* Hand off to network device */
532  netdev_rx ( netdev, iobuf );
533 }
void netdev_rx_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Discard received packet.
Definition: netdevice.c:501
static struct net_device * netdev
Definition: gdbudp.c:52
A network device.
Definition: netdevice.h:348
#define ENODEV
No such device.
Definition: errno.h:509
static struct net_device * vlan_find(struct net_device *trunk, unsigned int tag)
Identify VLAN device.
Definition: vlan.c:202
void netdev_rx(struct net_device *netdev, struct io_buffer *iobuf)
Add packet to receive queue.
Definition: netdevice.c:470
uint64_t tag
Identity tag.
Definition: edd.h:30
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

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

544  {
545  struct net_device *vlan;
546 
547  /* Identify VLAN device, if applicable */
548  if ( tag && ( ( vlan = vlan_find ( netdev, tag ) ) != NULL ) )
549  netdev = vlan;
550 
551  /* Hand off to network device */
552  netdev_rx_err ( netdev, iobuf, rc );
553 }
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:501
static struct net_device * netdev
Definition: gdbudp.c:52
A network device.
Definition: netdevice.h:348
static struct net_device * vlan_find(struct net_device *trunk, unsigned int tag)
Identify VLAN device.
Definition: vlan.c:202
uint64_t tag
Identity tag.
Definition: edd.h:30
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

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:227
#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_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:140
static void vlan_close(struct net_device *netdev)
Close VLAN device.
Definition: vlan.c:75
static void vlan_irq(struct net_device *netdev, int enable)
Enable/disable interrupts on VLAN device.
Definition: vlan.c:153
static int vlan_open(struct net_device *netdev)
Open VLAN device.
Definition: vlan.c:64
static int vlan_transmit(struct net_device *netdev, struct io_buffer *iobuf)
Transmit packet on VLAN device.
Definition: vlan.c:88

VLAN device operations.

Definition at line 164 of file vlan.c.

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

◆ __net_driver

struct net_driver vlan_driver __net_driver
Initial value:
= {
.name = "VLAN",
.notify = vlan_notify,
.remove = vlan_remove,
}
static void vlan_notify(struct net_device *trunk)
Handle trunk network device link state change.
Definition: vlan.c:456
static void vlan_remove(struct net_device *trunk)
Destroy all VLAN devices for a given trunk.
Definition: vlan.c:496

VLAN driver.

Definition at line 505 of file vlan.c.