From b4706c88c9008f9cd258819c9c826466056a59ca Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Fri, 26 Nov 2010 00:58:36 +0000 Subject: [PATCH] [vlan] Provide vlan_can_be_trunk() Signed-off-by: Michael Brown --- src/include/ipxe/vlan.h | 1 + src/net/vlan.c | 31 +++++++++++++++++++++++-------- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/include/ipxe/vlan.h b/src/include/ipxe/vlan.h index 86d78bed..b4d06b87 100644 --- a/src/include/ipxe/vlan.h +++ b/src/include/ipxe/vlan.h @@ -59,6 +59,7 @@ struct vlan_header { */ #define VLAN_PRIORITY_IS_VALID( priority ) ( (priority) <= 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 ); diff --git a/src/net/vlan.c b/src/net/vlan.c index f0479e0f..b16c6934 100644 --- a/src/net/vlan.c +++ b/src/net/vlan.c @@ -280,20 +280,35 @@ struct net_protocol vlan_protocol __net_protocol = { }; /** - * Create VLAN device + * Check if network device can be used as a VLAN trunk device * * @v trunk Trunk network device - * @v tag VLAN tag - * @v priority Default VLAN priority - * @ret rc Return status code + * @ret is_ok Trunk network device is usable * - * The VLAN device will be created as an Ethernet device. (We cannot + * 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. + */ +int vlan_can_be_trunk ( struct net_device *trunk ) { + + return ( ( trunk->ll_protocol->ll_addr_len == ETH_ALEN ) && + ( trunk->op != &vlan_operations ) ); +} + +/** + * Create VLAN device + * + * @v trunk Trunk network device + * @v tag VLAN tag + * @v priority Default VLAN priority + * @ret rc Return status code */ int vlan_create ( struct net_device *trunk, unsigned int tag, unsigned int priority ) { @@ -313,9 +328,9 @@ int vlan_create ( struct net_device *trunk, unsigned int tag, } /* Sanity checks */ - if ( trunk->ll_protocol->ll_addr_len != ETH_ALEN ) { - DBGC ( trunk, "VLAN %s cannot create VLAN for %s device\n", - trunk->name, trunk->ll_protocol->name ); + if ( ! vlan_can_be_trunk ( trunk ) ) { + DBGC ( trunk, "VLAN %s cannot create VLAN on non-trunk " + "device\n", trunk->name ); rc = -ENOTTY; goto err_sanity; }