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 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 FILE_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 
47 struct net_protocol vlan_protocol __net_protocol;
48 
49 /** VLAN device private data */
50 struct vlan_device {
51  /** Trunk network device */
52  struct net_device *trunk;
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 */
63 static unsigned int vlan_auto_tag;
64 
65 /**
66  * Open VLAN device
67  *
68  * @v netdev Network device
69  * @ret rc Return status code
70  */
71 static 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  */
82 static 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  */
95 static 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;
99  struct ll_protocol *ll_protocol;
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 */
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  */
147 static 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  */
160 static 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  */
184 static 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 ) )
195  netdev_open ( netdev );
196  } else {
197  if ( netdev_is_open ( netdev ) )
198  netdev_close ( 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  */
209 struct net_device * vlan_find ( struct net_device *trunk, unsigned int tag ) {
210  struct net_device *netdev;
211  struct vlan_device *vlan;
212 
213  for_each_netdev ( netdev ) {
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  */
233 static 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];
241  uint16_t tag;
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 */
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 */
290 struct 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  */
302 unsigned 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  */
344 int 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;
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  */
434 int vlan_destroy ( struct net_device *netdev ) {
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  */
463 void vlan_auto ( const void *ll_addr, unsigned int tag ) {
464 
465  /* Record link-layer address and VLAN tag */
467  vlan_auto_tag = 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  */
477 static 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  */
505 static void vlan_notify ( struct net_device *trunk, void *priv __unused ) {
506  struct net_device *netdev;
507  struct vlan_device *vlan;
508 
509  for_each_netdev ( netdev ) {
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  */
524 static int vlan_remove_first ( struct net_device *trunk ) {
525  struct net_device *netdev;
526  struct vlan_device *vlan;
527 
528  for_each_netdev ( netdev ) {
529  if ( netdev->op != &vlan_operations )
530  continue;
531  vlan = netdev->priv;
532  if ( vlan->trunk == trunk ) {
533  vlan_destroy ( netdev );
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  */
546 static 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 */
555 struct 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  */
569 void 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  */
594 void 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 iob_pull(iobuf, len)
Definition: iobuf.h:107
#define VLAN_TAG(tci)
Extract VLAN tag from tag control information.
Definition: vlan.h:30
#define EINVAL
Invalid argument.
Definition: errno.h:429
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned short uint16_t
Definition: stdint.h:11
const char * name
Protocol name.
Definition: netdevice.h:67
uint16_t tci
Tag control information.
Definition: vlan.h:19
void netdev_rx_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Discard received packet.
Definition: netdevice.c:587
unsigned int vlan_tci(struct net_device *netdev)
Get the VLAN tag control information.
Definition: vlan.c:302
struct net_device * trunk
Trunk network device.
Definition: vlan.c:52
uint8_t ll_addr_len
Link-layer address length.
Definition: netdevice.h:199
static struct net_device_operations vlan_operations
VLAN device operations.
Definition: vlan.c:171
#define FEATURE_PROTOCOL
Network protocols.
Definition: features.h:22
int(* open)(struct net_device *netdev)
Open network device.
Definition: netdevice.h:223
#define VLAN_TCI(tag, priority)
Construct VLAN tag control information.
Definition: vlan.h:47
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
struct net_protocol vlan_protocol __net_protocol
VLAN protocol.
Definition: vlan.c:47
uint16_t net_proto
Encapsulated protocol.
Definition: vlan.h:21
Error codes.
#define iob_push(iobuf, len)
Definition: iobuf.h:89
I/O buffers.
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:153
#define EPIPE
Broken pipe.
Definition: errno.h:620
VLAN device private data.
Definition: vlan.c:50
#define DBGC(...)
Definition: compiler.h:505
unsigned int state
Current device state.
Definition: netdevice.h:396
#define ntohs(value)
Definition: byteswap.h:137
#define VLAN_TAG_IS_VALID(tag)
Check VLAN tag is valid.
Definition: vlan.h:55
static void vlan_notify(struct net_device *trunk, void *priv __unused)
Handle trunk network device link state change.
Definition: vlan.c:505
struct net_device_operations * op
Network device operations.
Definition: netdevice.h:370
A network upper-layer driver.
Definition: netdevice.h:477
static int vlan_remove_first(struct net_device *trunk)
Destroy first VLAN device for a given trunk.
Definition: vlan.c:524
A link-layer protocol.
Definition: netdevice.h:115
int vlan_create(struct net_device *trunk, unsigned int tag, unsigned int priority)
Create VLAN device.
Definition: vlan.c:344
struct net_device * vlan_find(struct net_device *trunk, unsigned int tag)
Identify VLAN device.
Definition: vlan.c:209
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
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
Definition: netdevice.h:519
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
#define list_del(list)
Delete an entry from a list.
Definition: list.h:120
#define ENOMEM
Not enough space.
Definition: errno.h:535
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:217
void * memcpy(void *dest, const void *src, size_t len) __nonnull
const char * name
Name.
Definition: netdevice.h:479
static int netdev_is_open(struct net_device *netdev)
Check whether or not network device is open.
Definition: netdevice.h:662
void vlan_auto(const void *ll_addr, unsigned int tag)
Configure automatic VLAN device.
Definition: vlan.c:463
A VLAN header.
Definition: vlan.h:17
int link_rc
Link status code.
Definition: netdevice.h:402
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition: netdevice.h:576
Ethernet protocol.
FILE_SECBOOT(PERMITTED)
#define VLAN_PRIORITY_IS_VALID(priority)
Check VLAN priority is valid.
Definition: vlan.h:63
static void vlan_poll(struct net_device *netdev)
Poll VLAN device.
Definition: vlan.c:147
void * priv
Driver private data.
Definition: netdevice.h:432
static int vlan_probe(struct net_device *trunk, void *priv __unused)
Create automatic VLAN device.
Definition: vlan.c:477
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
static void vlan_sync(struct net_device *netdev)
Synchronise VLAN device.
Definition: vlan.c:184
static struct net_device * netdev
Definition: gdbudp.c:53
Feature list.
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition: netdevice.c:942
void netdev_poll(struct net_device *netdev)
Poll for completed and received packets on network device.
Definition: netdevice.c:613
uint8_t flags
Flags.
Definition: ena.h:18
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
static void vlan_close(struct net_device *netdev)
Close VLAN device.
Definition: vlan.c:82
static uint8_t vlan_auto_ll_addr[ETH_ALEN]
Automatic VLAN device link-layer address.
Definition: vlan.c:60
#define for_each_netdev(netdev)
Iterate over all network devices.
Definition: netdevice.h:547
int register_netdev(struct net_device *netdev)
Register network device.
Definition: netdevice.c:760
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:160
FEATURE(FEATURE_PROTOCOL, "VLAN", DHCP_EB_FEATURE_VLAN, 1)
void netdev_irq(struct net_device *netdev, int enable)
Enable or disable interrupts.
Definition: netdevice.c:971
A network device.
Definition: netdevice.h:353
void netdev_link_err(struct net_device *netdev, int rc)
Mark network device as having a specific link state.
Definition: netdevice.c:208
#define ENODEV
No such device.
Definition: errno.h:510
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
Definition: netdevice.h:532
unsigned char uint8_t
Definition: stdint.h:10
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition: netdevice.h:565
#define ETH_ALEN
Definition: if_ether.h:9
int vlan_destroy(struct net_device *netdev)
Destroy VLAN device.
Definition: vlan.c:434
Network device operations.
Definition: netdevice.h:214
void netdev_rx(struct net_device *netdev, struct io_buffer *iobuf)
Add packet to receive queue.
Definition: netdevice.c:549
struct device * dev
Underlying hardware device.
Definition: netdevice.h:365
void netdev_close(struct net_device *netdev)
Close network device.
Definition: netdevice.c:896
A network-layer protocol.
Definition: netdevice.h:65
Network device management.
unsigned int tag
VLAN tag.
Definition: vlan.c:54
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
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
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:363
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:45
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
#define DBGC2(...)
Definition: compiler.h:522
static struct tlan_private * priv
Definition: tlan.c:225
#define ENOTTY
Inappropriate I/O control operation.
Definition: errno.h:595
static void vlan_irq(struct net_device *netdev, int enable)
Enable/disable interrupts on VLAN device.
Definition: vlan.c:160
uint16_t priority
Priotity.
Definition: stp.h:13
struct net_driver vlan_driver __net_driver
VLAN driver.
Definition: vlan.c:555
void * data
Start of data.
Definition: iobuf.h:53
static int vlan_open(struct net_device *netdev)
Open VLAN device.
Definition: vlan.c:71
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
struct net_device * alloc_etherdev(size_t priv_size)
Allocate Ethernet device.
Definition: ethernet.c:265
static void vlan_remove(struct net_device *trunk, void *priv __unused)
Destroy all VLAN devices for a given trunk.
Definition: vlan.c:546
Virtual LANs.
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
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:383
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:388
unsigned int priority
Default priority.
Definition: vlan.c:56
static int vlan_transmit(struct net_device *netdev, struct io_buffer *iobuf)
Transmit packet on VLAN device.
Definition: vlan.c:95
uint64_t tag
Identity tag.
Definition: edd.h:31
#define NETDEV_IRQ_UNSUPPORTED
Network device interrupts are unsupported.
Definition: netdevice.h:453
#define DHCP_EB_FEATURE_VLAN
VLAN support.
Definition: features.h:55
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:115
uint8_t hw_addr[MAX_HW_ADDR_LEN]
Hardware address.
Definition: netdevice.h:382
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
static unsigned int vlan_auto_tag
Automatic VLAN tag.
Definition: vlan.c:63
String functions.
static int netdev_irq_supported(struct net_device *netdev)
Check whether or not network device supports interrupts.
Definition: netdevice.h:673
int netdev_open(struct net_device *netdev)
Open network device.
Definition: netdevice.c:862
#define htons(value)
Definition: byteswap.h:136
#define ETH_P_8021Q
Definition: if_ether.h:22
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:373
A persistent I/O buffer.
Definition: iobuf.h:38