aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2023-01-15 22:35:44 +0000
committerMichael Brown <mcb30@ipxe.org>2023-01-15 22:35:44 +0000
commitf07630c74f3d67906baf820f080b5d0e5ad49ca4 (patch)
tree8258e2c1ddd8c916ef9fd2a5e3778bfb1dd7439c /src
parent5a2fa6040e17562ce742df09aa20b8774b3879c5 (diff)
downloadipxe-f07630c74f3d67906baf820f080b5d0e5ad49ca4.zip
ipxe-f07630c74f3d67906baf820f080b5d0e5ad49ca4.tar.gz
ipxe-f07630c74f3d67906baf820f080b5d0e5ad49ca4.tar.bz2
[vlan] Support automatic VLAN device creation
Add the ability to automatically create a VLAN device for a specified trunk device link-layer address and VLAN tag. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src')
-rw-r--r--src/include/ipxe/vlan.h1
-rw-r--r--src/net/vlan.c48
2 files changed, 49 insertions, 0 deletions
diff --git a/src/include/ipxe/vlan.h b/src/include/ipxe/vlan.h
index 8bf7923..20bbc89 100644
--- a/src/include/ipxe/vlan.h
+++ b/src/include/ipxe/vlan.h
@@ -80,6 +80,7 @@ extern int vlan_can_be_trunk ( struct net_device *trunk );
extern int vlan_create ( struct net_device *trunk, unsigned int tag,
unsigned int priority );
extern int vlan_destroy ( struct net_device *netdev );
+extern void vlan_auto ( const void *ll_addr, unsigned int tag );
extern void vlan_netdev_rx ( struct net_device *netdev, unsigned int tag,
struct io_buffer *iobuf );
extern void vlan_netdev_rx_err ( struct net_device *netdev, unsigned int tag,
diff --git a/src/net/vlan.c b/src/net/vlan.c
index 81ec623..d73a957 100644
--- a/src/net/vlan.c
+++ b/src/net/vlan.c
@@ -55,6 +55,12 @@ struct vlan_device {
unsigned int priority;
};
+/** Automatic VLAN device link-layer address */
+static uint8_t vlan_auto_ll_addr[ETH_ALEN];
+
+/** Automatic VLAN tag */
+static unsigned int vlan_auto_tag;
+
/**
* Open VLAN device
*
@@ -448,6 +454,47 @@ int vlan_destroy ( struct net_device *netdev ) {
}
/**
+ * Configure automatic VLAN device
+ *
+ * @v ll_addr Link-layer address
+ * @v tag VLAN tag
+ */
+void vlan_auto ( const void *ll_addr, unsigned int tag ) {
+
+ /* Record link-layer address and VLAN tag */
+ memcpy ( vlan_auto_ll_addr, ll_addr, ETH_ALEN );
+ vlan_auto_tag = tag;
+}
+
+/**
+ * Create automatic VLAN device
+ *
+ * @v trunk Trunk network device
+ * @ret rc Return status code
+ */
+static int vlan_probe ( struct net_device *trunk ) {
+ int rc;
+
+ /* Do nothing unless an automatic VLAN exists */
+ if ( ! vlan_auto_tag )
+ return 0;
+
+ /* Ignore non-trunk devices */
+ if ( ! vlan_can_be_trunk ( trunk ) )
+ return 0;
+
+ /* Ignore non-matching link-layer addresses */
+ if ( memcmp ( trunk->ll_addr, vlan_auto_ll_addr, ETH_ALEN ) != 0 )
+ return 0;
+
+ /* Create automatic VLAN device */
+ if ( ( rc = vlan_create ( trunk, vlan_auto_tag, 0 ) ) != 0 )
+ return rc;
+
+ return 0;
+}
+
+/**
* Handle trunk network device link state change
*
* @v trunk Trunk network device
@@ -503,6 +550,7 @@ static void vlan_remove ( struct net_device *trunk ) {
/** VLAN driver */
struct net_driver vlan_driver __net_driver = {
.name = "VLAN",
+ .probe = vlan_probe,
.notify = vlan_notify,
.remove = vlan_remove,
};