iPXE
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.
static void vlan_close (struct net_device *netdev)
 Close VLAN device.
static int vlan_transmit (struct net_device *netdev, struct io_buffer *iobuf)
 Transmit packet on VLAN device.
static void vlan_poll (struct net_device *netdev)
 Poll VLAN device.
static void vlan_irq (struct net_device *netdev, int enable)
 Enable/disable interrupts on VLAN device.
static void vlan_sync (struct net_device *netdev)
 Synchronise VLAN device.
struct net_devicevlan_find (struct net_device *trunk, unsigned int tag)
 Identify VLAN device.
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.
unsigned int vlan_tci (struct net_device *netdev)
 Get the VLAN tag control information.
int vlan_can_be_trunk (struct net_device *trunk)
 Check if network device can be used as a VLAN trunk device.
int vlan_create (struct net_device *trunk, unsigned int tag, unsigned int priority)
 Create VLAN device.
int vlan_destroy (struct net_device *netdev)
 Destroy VLAN device.
void vlan_auto (const void *ll_addr, unsigned int tag)
 Configure automatic VLAN device.
static int vlan_probe (struct net_device *trunk, void *priv __unused)
 Create automatic VLAN device.
static void vlan_notify (struct net_device *trunk, void *priv __unused)
 Handle trunk network device link state change.
static int vlan_remove_first (struct net_device *trunk)
 Destroy first VLAN device for a given trunk.
static void vlan_remove (struct net_device *trunk, void *priv __unused)
 Destroy all VLAN devices for a given trunk.
void vlan_netdev_rx (struct net_device *netdev, unsigned int tag, struct io_buffer *iobuf)
 Add VLAN tag-stripped packet to receive queue.
void vlan_netdev_rx_err (struct net_device *netdev, unsigned int tag, struct io_buffer *iobuf, int rc)
 Discard received VLAN tag-stripped packet.

Variables

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

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

◆ vlan_open()

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}
static struct net_device * netdev
Definition gdbudp.c:53
int netdev_open(struct net_device *netdev)
Open network device.
Definition netdevice.c:866
VLAN device private data.
Definition vlan.c:50
struct net_device * trunk
Trunk network device.
Definition vlan.c:52

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

◆ vlan_close()

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}
void netdev_close(struct net_device *netdev)
Close network device.
Definition netdevice.c:900

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

◆ vlan_transmit()

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;
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 */
110 ll_protocol = netdev->ll_protocol;
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:3
unsigned short uint16_t
Definition stdint.h:11
unsigned char uint8_t
Definition stdint.h:10
uint8_t flags
Flags.
Definition ena.h:7
#define DBGC(...)
Definition compiler.h:530
#define ETH_ALEN
Definition if_ether.h:9
#define htons(value)
Definition byteswap.h:136
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define iob_push(iobuf, len)
Definition iobuf.h:149
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition iobuf.h:277
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
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:1078
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
struct list_head list
List of which this buffer is a member.
Definition iobuf.h:105
A link-layer protocol.
Definition netdevice.h:115
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
A network device.
Definition netdevice.h:353
unsigned int priority
Default priority.
Definition vlan.c:56
unsigned int tag
VLAN tag.
Definition vlan.c:54
A VLAN header.
Definition vlan.h:17
uint16_t net_proto
Encapsulated protocol.
Definition vlan.h:21
uint16_t tci
Tag control information.
Definition vlan.h:19
#define VLAN_TCI(tag, priority)
Construct VLAN tag control information.
Definition vlan.h:47

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

◆ vlan_poll()

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}
void netdev_poll(struct net_device *netdev)
Poll for completed and received packets on network device.
Definition netdevice.c:613

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

◆ vlan_irq()

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}
void netdev_irq(struct net_device *netdev, int enable)
Enable or disable interrupts.
Definition netdevice.c:975

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

◆ vlan_sync()

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 ) )
196 } else {
197 if ( netdev_is_open ( netdev ) )
199 }
200}
void netdev_link_err(struct net_device *netdev, int rc)
Mark network device as having a specific link state.
Definition netdevice.c:208
static int netdev_is_open(struct net_device *netdev)
Check whether or not network device is open.
Definition netdevice.h:665
int link_rc
Link status code.
Definition netdevice.h:402

References net_device::link_rc, netdev, netdev_close(), netdev_is_open(), netdev_link_err(), netdev_open(), 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
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}
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
uint64_t tag
Identity tag.
Definition edd.h:1
#define for_each_netdev(netdev)
Iterate over all network devices.
Definition netdevice.h:550
static struct net_device_operations vlan_operations
VLAN device operations.
Definition vlan.c:171

References for_each_netdev, netdev, NULL, 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()

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;
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];
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 vlanhdr = iobuf->data;
252
253 /* Identify VLAN device */
254 tag = VLAN_TAG ( ntohs ( vlanhdr->tci ) );
255 netdev = vlan_find ( trunk, tag );
256 if ( ! netdev ) {
257 DBGC2 ( trunk, "VLAN %s received packet for unknown VLAN "
258 "%d\n", trunk->name, tag );
259 rc = -EPIPE;
260 goto err_no_vlan;
261 }
262
263 /* Strip VLAN header and preserve original link-layer header fields */
264 iob_pull ( iobuf, sizeof ( *vlanhdr ) );
265 ll_protocol = trunk->ll_protocol;
266 memcpy ( ll_dest_copy, ll_dest, ETH_ALEN );
267 memcpy ( ll_source_copy, ll_source, ETH_ALEN );
268
269 /* Reconstruct link-layer header for VLAN device */
270 ll_protocol = netdev->ll_protocol;
271 if ( ( rc = ll_protocol->push ( netdev, iobuf, ll_dest_copy,
272 ll_source_copy,
273 vlanhdr->net_proto ) ) != 0 ) {
274 DBGC ( netdev, "VLAN %s could not reconstruct link-layer "
275 "header: %s\n", netdev->name, strerror ( rc ) );
276 goto err_ll_push;
277 }
278
279 /* Enqueue packet on VLAN device */
280 netdev_rx ( netdev, iob_disown ( iobuf ) );
281 return 0;
282
283 err_ll_push:
284 err_no_vlan:
285 err_sanity:
286 free_iob ( iobuf );
287 return rc;
288}
#define DBGC2(...)
Definition compiler.h:547
#define EINVAL
Invalid argument.
Definition errno.h:472
#define EPIPE
Broken pipe.
Definition errno.h:663
#define ntohs(value)
Definition byteswap.h:137
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:220
#define iob_pull(iobuf, len)
Definition iobuf.h:167
void netdev_rx(struct net_device *netdev, struct io_buffer *iobuf)
Add packet to receive queue.
Definition netdevice.c:549
void * data
Start of data.
Definition iobuf.h:113
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
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition netdevice.h:373
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition netdevice.h:363
struct net_device * vlan_find(struct net_device *trunk, unsigned int tag)
Identify VLAN device.
Definition vlan.c:209
#define VLAN_TAG(tci)
Extract VLAN tag from tag control information.
Definition vlan.h:30

References __unused, io_buffer::data, DBGC, DBGC2, EINVAL, EPIPE, ETH_ALEN, flags, 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 303 of file vlan.c.

303 {
304 struct vlan_device *vlan;
305
306 if ( netdev->op == &vlan_operations ) {
307 vlan = netdev->priv;
308 return ( VLAN_TCI ( vlan->tag, vlan->priority ) );
309 } else {
310 return 0;
311 }
312}

References netdev, vlan_device::priority, vlan_device::tag, vlan_operations, and VLAN_TCI.

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

331 {
332
333 return ( ( trunk->ll_protocol->ll_addr_len == ETH_ALEN ) &&
334 ( trunk->op != &vlan_operations ) );
335}
uint8_t ll_addr_len
Link-layer address length.
Definition netdevice.h:199
struct net_device_operations * op
Network device operations.
Definition netdevice.h:370

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

346 {
347 struct net_device *netdev;
348 struct vlan_device *vlan;
349 int rc;
350
351 /* If VLAN already exists, just update the priority */
352 if ( ( netdev = vlan_find ( trunk, tag ) ) != NULL ) {
353 vlan = netdev->priv;
354 if ( priority != vlan->priority ) {
355 DBGC ( netdev, "VLAN %s priority changed from %d to "
356 "%d\n", netdev->name, vlan->priority, priority );
357 }
358 vlan->priority = priority;
359 return 0;
360 }
361
362 /* Sanity checks */
363 if ( ! vlan_can_be_trunk ( trunk ) ) {
364 DBGC ( trunk, "VLAN %s cannot create VLAN on non-trunk "
365 "device\n", trunk->name );
366 rc = -ENOTTY;
367 goto err_sanity;
368 }
369 if ( ! VLAN_TAG_IS_VALID ( tag ) ) {
370 DBGC ( trunk, "VLAN %s cannot create VLAN with invalid tag "
371 "%d\n", trunk->name, tag );
372 rc = -EINVAL;
373 goto err_sanity;
374 }
375 if ( ! VLAN_PRIORITY_IS_VALID ( priority ) ) {
376 DBGC ( trunk, "VLAN %s cannot create VLAN with invalid "
377 "priority %d\n", trunk->name, priority );
378 rc = -EINVAL;
379 goto err_sanity;
380 }
381
382 /* Allocate and initialise structure */
383 netdev = alloc_etherdev ( sizeof ( *vlan ) );
384 if ( ! netdev ) {
385 rc = -ENOMEM;
386 goto err_alloc_etherdev;
387 }
389 netdev->dev = trunk->dev;
390 memcpy ( netdev->hw_addr, trunk->ll_addr, ETH_ALEN );
391 vlan = netdev->priv;
392 vlan->trunk = netdev_get ( trunk );
393 vlan->tag = tag;
394 vlan->priority = priority;
395
396 /* Construct VLAN device name */
397 snprintf ( netdev->name, sizeof ( netdev->name ), "%s-%d",
398 trunk->name, vlan->tag );
399
400 /* Mark device as not supporting interrupts, if applicable */
401 if ( ! netdev_irq_supported ( trunk ) )
403
404 /* Register VLAN device */
405 if ( ( rc = register_netdev ( netdev ) ) != 0 ) {
406 DBGC ( netdev, "VLAN %s could not register: %s\n",
407 netdev->name, strerror ( rc ) );
408 goto err_register;
409 }
410
411 /* Synchronise with trunk device */
412 vlan_sync ( netdev );
413
414 DBGC ( netdev, "VLAN %s created with tag %d and priority %d\n",
415 netdev->name, vlan->tag, vlan->priority );
416
417 return 0;
418
420 err_register:
422 netdev_put ( netdev );
423 netdev_put ( trunk );
424 err_alloc_etherdev:
425 err_sanity:
426 return rc;
427}
struct net_device * alloc_etherdev(size_t priv_size)
Allocate Ethernet device.
Definition ethernet.c:266
#define ENOMEM
Not enough space.
Definition errno.h:578
#define ENOTTY
Inappropriate I/O control operation.
Definition errno.h:638
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition netdevice.c:946
int register_netdev(struct net_device *netdev)
Register network device.
Definition netdevice.c:760
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition netdevice.h:568
static int netdev_irq_supported(struct net_device *netdev)
Check whether or not network device supports interrupts.
Definition netdevice.h:676
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
Definition netdevice.h:522
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
Definition netdevice.h:535
#define NETDEV_IRQ_UNSUPPORTED
Network device interrupts are unsupported.
Definition netdevice.h:453
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition netdevice.h:579
uint16_t priority
Priotity.
Definition stp.h:1
struct device * dev
Underlying hardware device.
Definition netdevice.h:365
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition netdevice.h:388
int vlan_can_be_trunk(struct net_device *trunk)
Check if network device can be used as a VLAN trunk device.
Definition vlan.c:331
static void vlan_sync(struct net_device *netdev)
Synchronise VLAN device.
Definition vlan.c:184
#define VLAN_TAG_IS_VALID(tag)
Check VLAN tag is valid.
Definition vlan.h:55
#define VLAN_PRIORITY_IS_VALID(priority)
Check VLAN priority is valid.
Definition vlan.h:63
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition vsprintf.c:383

References alloc_etherdev(), DBGC, net_device::dev, EINVAL, ENOMEM, ENOTTY, ETH_ALEN, 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, rc, register_netdev(), snprintf(), 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 435 of file vlan.c.

435 {
436 struct vlan_device *vlan = netdev->priv;
437 struct net_device *trunk;
438
439 /* Sanity check */
440 if ( netdev->op != &vlan_operations ) {
441 DBGC ( netdev, "VLAN %s cannot destroy non-VLAN device\n",
442 netdev->name );
443 return -ENOTTY;
444 }
445
446 DBGC ( netdev, "VLAN %s destroyed\n", netdev->name );
447
448 /* Remove VLAN device */
450 trunk = vlan->trunk;
452 netdev_put ( netdev );
453 netdev_put ( trunk );
454
455 return 0;
456}

References DBGC, ENOTTY, netdev, netdev_nullify(), netdev_put(), 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 464 of file vlan.c.

464 {
465
466 /* Record link-layer address and VLAN tag */
467 memcpy ( vlan_auto_ll_addr, ll_addr, ETH_ALEN );
469}
static uint8_t vlan_auto_ll_addr[ETH_ALEN]
Automatic VLAN device link-layer address.
Definition vlan.c:60
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()

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

478 {
479 int rc;
480
481 /* Do nothing unless an automatic VLAN exists */
482 if ( ! vlan_auto_tag )
483 return 0;
484
485 /* Ignore non-trunk devices */
486 if ( ! vlan_can_be_trunk ( trunk ) )
487 return 0;
488
489 /* Ignore non-matching link-layer addresses */
490 if ( memcmp ( trunk->ll_addr, vlan_auto_ll_addr, ETH_ALEN ) != 0 )
491 return 0;
492
493 /* Create automatic VLAN device */
494 if ( ( rc = vlan_create ( trunk, vlan_auto_tag, 0 ) ) != 0 )
495 return rc;
496
497 return 0;
498}
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115
int vlan_create(struct net_device *trunk, unsigned int tag, unsigned int priority)
Create VLAN device.
Definition vlan.c:345

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

◆ vlan_notify()

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

506 {
507 struct net_device *netdev;
508 struct vlan_device *vlan;
509
511 if ( netdev->op != &vlan_operations )
512 continue;
513 vlan = netdev->priv;
514 if ( vlan->trunk == trunk )
515 vlan_sync ( netdev );
516 }
517}

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

◆ vlan_remove_first()

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

525 {
526 struct net_device *netdev;
527 struct vlan_device *vlan;
528
530 if ( netdev->op != &vlan_operations )
531 continue;
532 vlan = netdev->priv;
533 if ( vlan->trunk == trunk ) {
535 return 1;
536 }
537 }
538 return 0;
539}
int vlan_destroy(struct net_device *netdev)
Destroy VLAN device.
Definition vlan.c:435

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

Referenced by vlan_remove().

◆ vlan_remove()

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

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

References __unused, priv, 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 570 of file vlan.c.

571 {
572 struct net_device *vlan;
573
574 /* Identify VLAN device, if applicable */
575 if ( tag ) {
576 if ( ( vlan = vlan_find ( netdev, tag ) ) == NULL ) {
577 netdev_rx_err ( netdev, iobuf, -ENODEV );
578 return;
579 }
580 netdev = vlan;
581 }
582
583 /* Hand off to network device */
584 netdev_rx ( netdev, iobuf );
585}
#define ENODEV
No such device.
Definition errno.h:553
void netdev_rx_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Discard received packet.
Definition netdevice.c:587

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 __unused,
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 595 of file vlan.c.

596 {
597 struct net_device *vlan;
598
599 /* Identify VLAN device, if applicable */
600 if ( tag && ( ( vlan = vlan_find ( netdev, tag ) ) != NULL ) )
601 netdev = vlan;
602
603 /* Hand off to network device */
604 netdev_rx_err ( netdev, iobuf, rc );
605}

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,
}
#define ETH_P_8021Q
Definition if_ether.h:22
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

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 int vlan_transmit(struct net_device *netdev, struct io_buffer *iobuf)
Transmit packet on VLAN device.
Definition vlan.c:95
static int vlan_open(struct net_device *netdev)
Open VLAN device.
Definition vlan.c:71
static void vlan_irq(struct net_device *netdev, int enable)
Enable/disable interrupts on VLAN device.
Definition vlan.c:160
static void vlan_close(struct net_device *netdev)
Close VLAN device.
Definition vlan.c:82
static void vlan_poll(struct net_device *netdev)
Poll VLAN device.
Definition vlan.c:147

VLAN device operations.

Definition at line 171 of file vlan.c.

171 {
172 .open = vlan_open,
173 .close = vlan_close,
174 .transmit = vlan_transmit,
175 .poll = vlan_poll,
176 .irq = vlan_irq,
177};

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 int vlan_probe(struct net_device *trunk, void *priv __unused)
Create automatic VLAN device.
Definition vlan.c:478
static void vlan_notify(struct net_device *trunk, void *priv __unused)
Handle trunk network device link state change.
Definition vlan.c:506
static void vlan_remove(struct net_device *trunk, void *priv __unused)
Destroy all VLAN devices for a given trunk.
Definition vlan.c:547

VLAN driver.

Definition at line 556 of file vlan.c.

556 {
557 .name = "VLAN",
558 .probe = vlan_probe,
559 .notify = vlan_notify,
560 .remove = vlan_remove,
561};