iPXE
vlan.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2010 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25FILE_SECBOOT ( PERMITTED );
26
27#include <stdint.h>
28#include <string.h>
29#include <stdio.h>
30#include <errno.h>
31#include <byteswap.h>
32#include <ipxe/features.h>
33#include <ipxe/if_ether.h>
34#include <ipxe/ethernet.h>
35#include <ipxe/netdevice.h>
36#include <ipxe/iobuf.h>
37#include <ipxe/vlan.h>
38
39/** @file
40 *
41 * Virtual LANs
42 *
43 */
44
46
47struct net_protocol vlan_protocol __net_protocol;
48
49/** VLAN device private data */
51 /** Trunk network device */
53 /** VLAN tag */
54 unsigned int tag;
55 /** Default priority */
56 unsigned int priority;
57};
58
59/** Automatic VLAN device link-layer address */
61
62/** Automatic VLAN tag */
63static unsigned int vlan_auto_tag;
64
65/**
66 * Open VLAN device
67 *
68 * @v netdev Network device
69 * @ret rc Return status code
70 */
71static int vlan_open ( struct net_device *netdev ) {
72 struct vlan_device *vlan = netdev->priv;
73
74 return netdev_open ( vlan->trunk );
75}
76
77/**
78 * Close VLAN device
79 *
80 * @v netdev Network device
81 */
82static void vlan_close ( struct net_device *netdev ) {
83 struct vlan_device *vlan = netdev->priv;
84
85 netdev_close ( vlan->trunk );
86}
87
88/**
89 * Transmit packet on VLAN device
90 *
91 * @v netdev Network device
92 * @v iobuf I/O buffer
93 * @ret rc Return status code
94 */
95static int vlan_transmit ( struct net_device *netdev,
96 struct io_buffer *iobuf ) {
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}
141
142/**
143 * Poll VLAN device
144 *
145 * @v netdev Network device
146 */
147static void vlan_poll ( struct net_device *netdev ) {
148 struct vlan_device *vlan = netdev->priv;
149
150 /* Poll trunk device */
151 netdev_poll ( vlan->trunk );
152}
153
154/**
155 * Enable/disable interrupts on VLAN device
156 *
157 * @v netdev Network device
158 * @v enable Interrupts should be enabled
159 */
160static void vlan_irq ( struct net_device *netdev, int enable ) {
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}
169
170/** VLAN device operations */
172 .open = vlan_open,
173 .close = vlan_close,
174 .transmit = vlan_transmit,
175 .poll = vlan_poll,
176 .irq = vlan_irq,
177};
178
179/**
180 * Synchronise VLAN device
181 *
182 * @v netdev Network device
183 */
184static void vlan_sync ( struct net_device *netdev ) {
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}
201
202/**
203 * Identify VLAN device
204 *
205 * @v trunk Trunk network device
206 * @v tag VLAN tag
207 * @ret netdev VLAN device, if any
208 */
209struct net_device * vlan_find ( struct net_device *trunk, unsigned int tag ) {
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}
222
223/**
224 * Process incoming VLAN packet
225 *
226 * @v iobuf I/O buffer
227 * @v trunk Trunk network device
228 * @v ll_dest Link-layer destination address
229 * @v ll_source Link-layer source address
230 * @v flags Packet flags
231 * @ret rc Return status code
232 */
233static int vlan_rx ( struct io_buffer *iobuf, struct net_device *trunk,
234 const void *ll_dest, const void *ll_source,
235 unsigned int flags __unused ) {
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}
288
289/** VLAN protocol */
290struct net_protocol vlan_protocol __net_protocol = {
291 .name = "VLAN",
292 .net_proto = htons ( ETH_P_8021Q ),
293 .rx = vlan_rx,
294};
295
296/**
297 * Get the VLAN tag control information
298 *
299 * @v netdev Network device
300 * @ret tci VLAN tag control information, or 0 if not a VLAN device
301 */
302unsigned int vlan_tci ( struct net_device *netdev ) {
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}
312
313/**
314 * Check if network device can be used as a VLAN trunk device
315 *
316 * @v trunk Trunk network device
317 * @ret is_ok Trunk network device is usable
318 *
319 * VLAN devices will be created as Ethernet devices. (We cannot
320 * simply clone the link layer of the trunk network device, because
321 * this link layer may expect the network device structure to contain
322 * some link-layer-private data.) The trunk network device must
323 * therefore have a link layer that is in some sense 'compatible' with
324 * Ethernet; specifically, it must have link-layer addresses that are
325 * the same length as Ethernet link-layer addresses.
326 *
327 * As an additional check, and primarily to assist with the sanity of
328 * the FCoE code, we refuse to allow nested VLANs.
329 */
331
332 return ( ( trunk->ll_protocol->ll_addr_len == ETH_ALEN ) &&
333 ( trunk->op != &vlan_operations ) );
334}
335
336/**
337 * Create VLAN device
338 *
339 * @v trunk Trunk network device
340 * @v tag VLAN tag
341 * @v priority Default VLAN priority
342 * @ret rc Return status code
343 */
344int vlan_create ( struct net_device *trunk, unsigned int tag,
345 unsigned int priority ) {
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}
427
428/**
429 * Destroy VLAN device
430 *
431 * @v netdev Network device
432 * @ret rc Return status code
433 */
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}
456
457/**
458 * Configure automatic VLAN device
459 *
460 * @v ll_addr Link-layer address
461 * @v tag VLAN tag
462 */
463void vlan_auto ( const void *ll_addr, unsigned int tag ) {
464
465 /* Record link-layer address and VLAN tag */
468}
469
470/**
471 * Create automatic VLAN device
472 *
473 * @v trunk Trunk network device
474 * @v priv Private data
475 * @ret rc Return status code
476 */
477static int vlan_probe ( struct net_device *trunk, void *priv __unused ) {
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}
498
499/**
500 * Handle trunk network device link state change
501 *
502 * @v trunk Trunk network device
503 * @v priv Private data
504 */
505static void vlan_notify ( struct net_device *trunk, void *priv __unused ) {
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}
517
518/**
519 * Destroy first VLAN device for a given trunk
520 *
521 * @v trunk Trunk network device
522 * @ret found A VLAN device was found
523 */
524static int vlan_remove_first ( struct net_device *trunk ) {
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}
539
540/**
541 * Destroy all VLAN devices for a given trunk
542 *
543 * @v trunk Trunk network device
544 * @v priv Private data
545 */
546static void vlan_remove ( struct net_device *trunk, void *priv __unused ) {
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}
553
554/** VLAN driver */
555struct net_driver vlan_driver __net_driver = {
556 .name = "VLAN",
557 .probe = vlan_probe,
558 .notify = vlan_notify,
559 .remove = vlan_remove,
560};
561
562/**
563 * Add VLAN tag-stripped packet to receive queue
564 *
565 * @v netdev Network device
566 * @v tag VLAN tag, or zero
567 * @v iobuf I/O buffer
568 */
569void vlan_netdev_rx ( struct net_device *netdev, unsigned int tag,
570 struct io_buffer *iobuf ) {
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}
585
586/**
587 * Discard received VLAN tag-stripped packet
588 *
589 * @v netdev Network device
590 * @v tag VLAN tag, or zero
591 * @v iobuf I/O buffer, or NULL
592 * @v rc Packet status code
593 */
594void vlan_netdev_rx_err ( struct net_device *netdev, unsigned int tag,
595 struct io_buffer *iobuf, int rc ) {
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}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
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
uint64_t tag
Identity tag.
Definition edd.h:1
uint8_t flags
Flags.
Definition ena.h:7
Error codes.
struct net_device * alloc_etherdev(size_t priv_size)
Allocate Ethernet device.
Definition ethernet.c:265
Ethernet protocol.
static struct net_device * netdev
Definition gdbudp.c:53
#define __unused
Declare a variable or data structure as unused.
Definition compiler.h:573
#define DBGC2(...)
Definition compiler.h:522
#define DBGC(...)
Definition compiler.h:505
#define DHCP_EB_FEATURE_VLAN
VLAN support.
Definition features.h:55
#define FEATURE_PROTOCOL
Network protocols.
Definition features.h:22
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define EINVAL
Invalid argument.
Definition errno.h:429
#define EPIPE
Broken pipe.
Definition errno.h:620
#define ENOMEM
Not enough space.
Definition errno.h:535
#define ENODEV
No such device.
Definition errno.h:510
#define ENOTTY
Inappropriate I/O control operation.
Definition errno.h:595
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
#define ETH_ALEN
Definition if_ether.h:9
#define ETH_P_8021Q
Definition if_ether.h:22
#define htons(value)
Definition byteswap.h:136
#define ntohs(value)
Definition byteswap.h:137
String functions.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
I/O buffers.
#define iob_push(iobuf, len)
Definition iobuf.h:89
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition iobuf.h:217
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
Feature list.
#define FEATURE(category, text, feature_opt, version)
Declare a feature.
Definition features.h:101
#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
void netdev_link_err(struct net_device *netdev, int rc)
Mark network device as having a specific link state.
Definition netdevice.c:208
void netdev_rx(struct net_device *netdev, struct io_buffer *iobuf)
Add packet to receive queue.
Definition netdevice.c:549
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition netdevice.c:942
int netdev_open(struct net_device *netdev)
Open network device.
Definition netdevice.c:862
void netdev_close(struct net_device *netdev)
Close network device.
Definition netdevice.c:896
void netdev_rx_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Discard received packet.
Definition netdevice.c:587
int register_netdev(struct net_device *netdev)
Register network device.
Definition netdevice.c:760
void netdev_irq(struct net_device *netdev, int enable)
Enable or disable interrupts.
Definition netdevice.c:971
void netdev_poll(struct net_device *netdev)
Poll for completed and received packets on network device.
Definition netdevice.c:613
Network device management.
#define for_each_netdev(netdev)
Iterate over all network devices.
Definition netdevice.h:547
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition netdevice.h:565
static int netdev_is_open(struct net_device *netdev)
Check whether or not network device is open.
Definition netdevice.h:662
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
#define __net_driver
Declare a network driver.
Definition netdevice.h:507
#define __net_protocol
Declare a network-layer protocol.
Definition netdevice.h:474
uint16_t priority
Priotity.
Definition stp.h:1
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115
A persistent I/O buffer.
Definition iobuf.h:38
void * data
Start of data.
Definition iobuf.h:53
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(* 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
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
uint8_t ll_addr_len
Link-layer address length.
Definition netdevice.h:199
Network device operations.
Definition netdevice.h:214
A network device.
Definition netdevice.h:353
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition netdevice.h:373
struct net_device_operations * op
Network device operations.
Definition netdevice.h:370
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition netdevice.h:363
int link_rc
Link status code.
Definition netdevice.h:402
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
A network upper-layer driver.
Definition netdevice.h:477
A network-layer protocol.
Definition netdevice.h:65
VLAN device private data.
Definition vlan.c:50
unsigned int priority
Default priority.
Definition vlan.c:56
struct net_device * trunk
Trunk network device.
Definition vlan.c:52
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
static struct tlan_private * priv
Definition tlan.c:225
static int vlan_remove_first(struct net_device *trunk)
Destroy first VLAN device for a given trunk.
Definition vlan.c:524
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
void vlan_auto(const void *ll_addr, unsigned int tag)
Configure automatic VLAN device.
Definition vlan.c:463
struct net_device * vlan_find(struct net_device *trunk, unsigned int tag)
Identify VLAN device.
Definition vlan.c:209
static int vlan_transmit(struct net_device *netdev, struct io_buffer *iobuf)
Transmit packet on VLAN device.
Definition vlan.c:95
static struct net_device_operations vlan_operations
VLAN device operations.
Definition vlan.c:171
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
static void vlan_sync(struct net_device *netdev)
Synchronise VLAN device.
Definition vlan.c:184
void vlan_netdev_rx_err(struct net_device *netdev, unsigned int tag, struct io_buffer *iobuf, int rc)
Discard received VLAN tag-stripped packet.
Definition vlan.c:594
static int vlan_open(struct net_device *netdev)
Open VLAN device.
Definition vlan.c:71
static int vlan_probe(struct net_device *trunk, void *priv __unused)
Create automatic VLAN device.
Definition vlan.c:477
static uint8_t vlan_auto_ll_addr[ETH_ALEN]
Automatic VLAN device link-layer address.
Definition vlan.c:60
int vlan_destroy(struct net_device *netdev)
Destroy VLAN device.
Definition vlan.c:434
static unsigned int vlan_auto_tag
Automatic VLAN tag.
Definition vlan.c:63
static void vlan_irq(struct net_device *netdev, int enable)
Enable/disable interrupts on VLAN device.
Definition vlan.c:160
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_close(struct net_device *netdev)
Close VLAN device.
Definition vlan.c:82
void vlan_netdev_rx(struct net_device *netdev, unsigned int tag, struct io_buffer *iobuf)
Add VLAN tag-stripped packet to receive queue.
Definition vlan.c:569
unsigned int vlan_tci(struct net_device *netdev)
Get the VLAN tag control information.
Definition vlan.c:302
static void vlan_poll(struct net_device *netdev)
Poll VLAN device.
Definition vlan.c:147
static void vlan_remove(struct net_device *trunk, void *priv __unused)
Destroy all VLAN devices for a given trunk.
Definition vlan.c:546
int vlan_create(struct net_device *trunk, unsigned int tag, unsigned int priority)
Create VLAN device.
Definition vlan.c:344
Virtual LANs.
#define VLAN_TAG_IS_VALID(tag)
Check VLAN tag is valid.
Definition vlan.h:55
#define VLAN_TAG(tci)
Extract VLAN tag from tag control information.
Definition vlan.h:30
#define VLAN_TCI(tag, priority)
Construct VLAN tag control information.
Definition vlan.h:47
#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