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;
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}
289
290/** VLAN protocol */
291struct net_protocol vlan_protocol __net_protocol = {
292 .name = "VLAN",
293 .net_proto = htons ( ETH_P_8021Q ),
294 .rx = vlan_rx,
295};
296
297/**
298 * Get the VLAN tag control information
299 *
300 * @v netdev Network device
301 * @ret tci VLAN tag control information, or 0 if not a VLAN device
302 */
303unsigned int vlan_tci ( struct net_device *netdev ) {
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}
313
314/**
315 * Check if network device can be used as a VLAN trunk device
316 *
317 * @v trunk Trunk network device
318 * @ret is_ok Trunk network device is usable
319 *
320 * VLAN devices will be created as Ethernet devices. (We cannot
321 * simply clone the link layer of the trunk network device, because
322 * this link layer may expect the network device structure to contain
323 * some link-layer-private data.) The trunk network device must
324 * therefore have a link layer that is in some sense 'compatible' with
325 * Ethernet; specifically, it must have link-layer addresses that are
326 * the same length as Ethernet link-layer addresses.
327 *
328 * As an additional check, and primarily to assist with the sanity of
329 * the FCoE code, we refuse to allow nested VLANs.
330 */
332
333 return ( ( trunk->ll_protocol->ll_addr_len == ETH_ALEN ) &&
334 ( trunk->op != &vlan_operations ) );
335}
336
337/**
338 * Create VLAN device
339 *
340 * @v trunk Trunk network device
341 * @v tag VLAN tag
342 * @v priority Default VLAN priority
343 * @ret rc Return status code
344 */
345int vlan_create ( struct net_device *trunk, unsigned int tag,
346 unsigned int priority ) {
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}
428
429/**
430 * Destroy VLAN device
431 *
432 * @v netdev Network device
433 * @ret rc Return status code
434 */
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}
457
458/**
459 * Configure automatic VLAN device
460 *
461 * @v ll_addr Link-layer address
462 * @v tag VLAN tag
463 */
464void vlan_auto ( const void *ll_addr, unsigned int tag ) {
465
466 /* Record link-layer address and VLAN tag */
469}
470
471/**
472 * Create automatic VLAN device
473 *
474 * @v trunk Trunk network device
475 * @v priv Private data
476 * @ret rc Return status code
477 */
478static int vlan_probe ( struct net_device *trunk, void *priv __unused ) {
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}
499
500/**
501 * Handle trunk network device link state change
502 *
503 * @v trunk Trunk network device
504 * @v priv Private data
505 */
506static void vlan_notify ( struct net_device *trunk, void *priv __unused ) {
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}
518
519/**
520 * Destroy first VLAN device for a given trunk
521 *
522 * @v trunk Trunk network device
523 * @ret found A VLAN device was found
524 */
525static int vlan_remove_first ( struct net_device *trunk ) {
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}
540
541/**
542 * Destroy all VLAN devices for a given trunk
543 *
544 * @v trunk Trunk network device
545 * @v priv Private data
546 */
547static void vlan_remove ( struct net_device *trunk, void *priv __unused ) {
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}
554
555/** VLAN driver */
556struct net_driver vlan_driver __net_driver = {
557 .name = "VLAN",
558 .probe = vlan_probe,
559 .notify = vlan_notify,
560 .remove = vlan_remove,
561};
562
563/**
564 * Add VLAN tag-stripped packet to receive queue
565 *
566 * @v netdev Network device
567 * @v tag VLAN tag, or zero
568 * @v iobuf I/O buffer
569 */
570void vlan_netdev_rx ( struct net_device *netdev, unsigned int tag,
571 struct io_buffer *iobuf ) {
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}
586
587/**
588 * Discard received VLAN tag-stripped packet
589 *
590 * @v netdev Network device
591 * @v tag VLAN tag, or zero
592 * @v iobuf I/O buffer, or NULL
593 * @v rc Packet status code
594 */
595void vlan_netdev_rx_err ( struct net_device *netdev, unsigned int tag,
596 struct io_buffer *iobuf, int rc ) {
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}
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
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:266
Ethernet protocol.
static struct net_device * netdev
Definition gdbudp.c:53
#define __unused
Declare a variable or data structure as unused.
Definition compiler.h:598
#define DBGC2(...)
Definition compiler.h:547
#define DBGC(...)
Definition compiler.h:530
#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:921
#define EINVAL
Invalid argument.
Definition errno.h:472
#define EPIPE
Broken pipe.
Definition errno.h:663
#define ENOMEM
Not enough space.
Definition errno.h:578
#define ENODEV
No such device.
Definition errno.h:553
#define ENOTTY
Inappropriate I/O control operation.
Definition errno.h:638
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:951
#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:149
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition iobuf.h:277
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
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:1078
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:946
int netdev_open(struct net_device *netdev)
Open network device.
Definition netdevice.c:866
void netdev_close(struct net_device *netdev)
Close network device.
Definition netdevice.c:900
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:975
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:550
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition netdevice.h:568
static int netdev_is_open(struct net_device *netdev)
Check whether or not network device is open.
Definition netdevice.h:665
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
#define __net_driver
Declare a network driver.
Definition netdevice.h:510
#define __net_protocol
Declare a network-layer protocol.
Definition netdevice.h:477
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:98
void * data
Start of data.
Definition iobuf.h:113
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(* 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:480
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:525
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
void vlan_auto(const void *ll_addr, unsigned int tag)
Configure automatic VLAN device.
Definition vlan.c:464
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:595
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:478
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:435
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:506
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:570
unsigned int vlan_tci(struct net_device *netdev)
Get the VLAN tag control information.
Definition vlan.c:303
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:547
int vlan_create(struct net_device *trunk, unsigned int tag, unsigned int priority)
Create VLAN device.
Definition vlan.c:345
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