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:862
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:896

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:505
#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:89
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition iobuf.h:217
#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:1074
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:45
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:971

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:662
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:322
uint64_t tag
Identity tag.
Definition edd.h:1
#define for_each_netdev(netdev)
Iterate over all network devices.
Definition netdevice.h:547
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 = iobuf->data;
237 struct net_device *netdev;
238 struct ll_protocol *ll_protocol;
239 uint8_t ll_dest_copy[ETH_ALEN];
240 uint8_t ll_source_copy[ETH_ALEN];
242 int rc;
243
244 /* Sanity check */
245 if ( iob_len ( iobuf ) < sizeof ( *vlanhdr ) ) {
246 DBGC ( trunk, "VLAN %s received underlength packet (%zd "
247 "bytes)\n", trunk->name, iob_len ( iobuf ) );
248 rc = -EINVAL;
249 goto err_sanity;
250 }
251
252 /* Identify VLAN device */
253 tag = VLAN_TAG ( ntohs ( vlanhdr->tci ) );
254 netdev = vlan_find ( trunk, tag );
255 if ( ! netdev ) {
256 DBGC2 ( trunk, "VLAN %s received packet for unknown VLAN "
257 "%d\n", trunk->name, tag );
258 rc = -EPIPE;
259 goto err_no_vlan;
260 }
261
262 /* Strip VLAN header and preserve original link-layer header fields */
263 iob_pull ( iobuf, sizeof ( *vlanhdr ) );
264 ll_protocol = trunk->ll_protocol;
265 memcpy ( ll_dest_copy, ll_dest, ETH_ALEN );
266 memcpy ( ll_source_copy, ll_source, ETH_ALEN );
267
268 /* Reconstruct link-layer header for VLAN device */
269 ll_protocol = netdev->ll_protocol;
270 if ( ( rc = ll_protocol->push ( netdev, iobuf, ll_dest_copy,
271 ll_source_copy,
272 vlanhdr->net_proto ) ) != 0 ) {
273 DBGC ( netdev, "VLAN %s could not reconstruct link-layer "
274 "header: %s\n", netdev->name, strerror ( rc ) );
275 goto err_ll_push;
276 }
277
278 /* Enqueue packet on VLAN device */
279 netdev_rx ( netdev, iob_disown ( iobuf ) );
280 return 0;
281
282 err_ll_push:
283 err_no_vlan:
284 err_sanity:
285 free_iob ( iobuf );
286 return rc;
287}
#define DBGC2(...)
Definition compiler.h:522
#define EINVAL
Invalid argument.
Definition errno.h:429
#define EPIPE
Broken pipe.
Definition errno.h:620
#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:160
#define iob_pull(iobuf, len)
Definition iobuf.h:107
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:53
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 302 of file vlan.c.

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

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

330 {
331
332 return ( ( trunk->ll_protocol->ll_addr_len == ETH_ALEN ) &&
333 ( trunk->op != &vlan_operations ) );
334}
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 344 of file vlan.c.

345 {
346 struct net_device *netdev;
347 struct vlan_device *vlan;
348 int rc;
349
350 /* If VLAN already exists, just update the priority */
351 if ( ( netdev = vlan_find ( trunk, tag ) ) != NULL ) {
352 vlan = netdev->priv;
353 if ( priority != vlan->priority ) {
354 DBGC ( netdev, "VLAN %s priority changed from %d to "
355 "%d\n", netdev->name, vlan->priority, priority );
356 }
357 vlan->priority = priority;
358 return 0;
359 }
360
361 /* Sanity checks */
362 if ( ! vlan_can_be_trunk ( trunk ) ) {
363 DBGC ( trunk, "VLAN %s cannot create VLAN on non-trunk "
364 "device\n", trunk->name );
365 rc = -ENOTTY;
366 goto err_sanity;
367 }
368 if ( ! VLAN_TAG_IS_VALID ( tag ) ) {
369 DBGC ( trunk, "VLAN %s cannot create VLAN with invalid tag "
370 "%d\n", trunk->name, tag );
371 rc = -EINVAL;
372 goto err_sanity;
373 }
374 if ( ! VLAN_PRIORITY_IS_VALID ( priority ) ) {
375 DBGC ( trunk, "VLAN %s cannot create VLAN with invalid "
376 "priority %d\n", trunk->name, priority );
377 rc = -EINVAL;
378 goto err_sanity;
379 }
380
381 /* Allocate and initialise structure */
382 netdev = alloc_etherdev ( sizeof ( *vlan ) );
383 if ( ! netdev ) {
384 rc = -ENOMEM;
385 goto err_alloc_etherdev;
386 }
388 netdev->dev = trunk->dev;
389 memcpy ( netdev->hw_addr, trunk->ll_addr, ETH_ALEN );
390 vlan = netdev->priv;
391 vlan->trunk = netdev_get ( trunk );
392 vlan->tag = tag;
393 vlan->priority = priority;
394
395 /* Construct VLAN device name */
396 snprintf ( netdev->name, sizeof ( netdev->name ), "%s-%d",
397 trunk->name, vlan->tag );
398
399 /* Mark device as not supporting interrupts, if applicable */
400 if ( ! netdev_irq_supported ( trunk ) )
402
403 /* Register VLAN device */
404 if ( ( rc = register_netdev ( netdev ) ) != 0 ) {
405 DBGC ( netdev, "VLAN %s could not register: %s\n",
406 netdev->name, strerror ( rc ) );
407 goto err_register;
408 }
409
410 /* Synchronise with trunk device */
411 vlan_sync ( netdev );
412
413 DBGC ( netdev, "VLAN %s created with tag %d and priority %d\n",
414 netdev->name, vlan->tag, vlan->priority );
415
416 return 0;
417
419 err_register:
421 netdev_put ( netdev );
422 netdev_put ( trunk );
423 err_alloc_etherdev:
424 err_sanity:
425 return rc;
426}
struct net_device * alloc_etherdev(size_t priv_size)
Allocate Ethernet device.
Definition ethernet.c:265
#define ENOMEM
Not enough space.
Definition errno.h:535
#define ENOTTY
Inappropriate I/O control operation.
Definition errno.h:595
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition netdevice.c:942
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:565
static int netdev_irq_supported(struct net_device *netdev)
Check whether or not network device supports interrupts.
Definition netdevice.h:673
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
Definition netdevice.h:519
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
Definition netdevice.h:532
#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:576
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:330
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 434 of file vlan.c.

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

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

463 {
464
465 /* Record link-layer address and VLAN tag */
466 memcpy ( vlan_auto_ll_addr, ll_addr, ETH_ALEN );
468}
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 477 of file vlan.c.

477 {
478 int rc;
479
480 /* Do nothing unless an automatic VLAN exists */
481 if ( ! vlan_auto_tag )
482 return 0;
483
484 /* Ignore non-trunk devices */
485 if ( ! vlan_can_be_trunk ( trunk ) )
486 return 0;
487
488 /* Ignore non-matching link-layer addresses */
489 if ( memcmp ( trunk->ll_addr, vlan_auto_ll_addr, ETH_ALEN ) != 0 )
490 return 0;
491
492 /* Create automatic VLAN device */
493 if ( ( rc = vlan_create ( trunk, vlan_auto_tag, 0 ) ) != 0 )
494 return rc;
495
496 return 0;
497}
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:344

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

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

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

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

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

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

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

570 {
571 struct net_device *vlan;
572
573 /* Identify VLAN device, if applicable */
574 if ( tag ) {
575 if ( ( vlan = vlan_find ( netdev, tag ) ) == NULL ) {
576 netdev_rx_err ( netdev, iobuf, -ENODEV );
577 return;
578 }
579 netdev = vlan;
580 }
581
582 /* Hand off to network device */
583 netdev_rx ( netdev, iobuf );
584}
#define ENODEV
No such device.
Definition errno.h:510
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 594 of file vlan.c.

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

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:477
static void vlan_notify(struct net_device *trunk, void *priv __unused)
Handle trunk network device link state change.
Definition vlan.c:505
static void vlan_remove(struct net_device *trunk, void *priv __unused)
Destroy all VLAN devices for a given trunk.
Definition vlan.c:546

VLAN driver.

Definition at line 555 of file vlan.c.

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