[ipxe-devel] [PATCH 1/2] Prevent a netdevice (VLAN) to open/close twice.

Wissam Shoukair wissams at mellanox.com
Wed Mar 5 12:44:42 GMT 2014


[netdevice.h] Added 2 netdevice states.
[netdevice.c] When opening/closing a netdevice, check if its not already
in the initialization/closing process. This will prevent from a VLAN to
open/close itself while its already in the opening/closing process.

Signed-off-by: Wissam Shoukair <wissams at mellanox.com>
---
 src/include/ipxe/netdevice.h |  6 ++++++
 src/net/netdevice.c          | 32 +++++++++++++++++++++++++-------
 2 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/src/include/ipxe/netdevice.h b/src/include/ipxe/netdevice.h
index e9951dd..80002dd 100644
--- a/src/include/ipxe/netdevice.h
+++ b/src/include/ipxe/netdevice.h
@@ -362,6 +362,12 @@ struct net_device {
 	void *priv;
 };
 
+/** Network device is opening */
+#define NETDEV_INITIALIZING 0x0008
+
+/** Network device is closing */
+#define NETDEV_CLOSING 0x0010
+
 /** Network device is open */
 #define NETDEV_OPEN 0x0001
 
diff --git a/src/net/netdevice.c b/src/net/netdevice.c
index 02ba89f..27d3036 100644
--- a/src/net/netdevice.c
+++ b/src/net/netdevice.c
@@ -398,7 +398,7 @@ static void netdev_rx_flush ( struct net_device *netdev ) {
 static void free_netdev ( struct refcnt *refcnt ) {
 	struct net_device *netdev =
 		container_of ( refcnt, struct net_device, refcnt );
-	
+
 	netdev_tx_flush ( netdev );
 	netdev_rx_flush ( netdev );
 	clear_settings ( netdev_settings ( netdev ) );
@@ -500,14 +500,23 @@ int register_netdev ( struct net_device *netdev ) {
 int netdev_open ( struct net_device *netdev ) {
 	int rc;
 
-	/* Do nothing if device is already open */
-	if ( netdev->state & NETDEV_OPEN )
+	/* Do nothing if device is already open or if the device is
+	 * already in the initialization/closing process */
+	if ( ( netdev->state & NETDEV_OPEN ) ||
+		( netdev->state & NETDEV_INITIALIZING ) ||
+		( netdev->state & NETDEV_CLOSING ) )
 		return 0;
 
 	DBGC ( netdev, "NETDEV %s opening\n", netdev->name );
 
 	/* Open the device */
-	if ( ( rc = netdev->op->open ( netdev ) ) != 0 )
+	rc = netdev->op->open ( netdev );
+
+	/* Unmark netdev state - initlizing is done (maybe with error) */
+	netdev->state &= ~NETDEV_INITIALIZING;
+
+	/* Check if the device was opened successfully */
+	if ( rc != 0 )
 		return rc;
 
 	/* Mark as opened */
@@ -529,12 +538,18 @@ int netdev_open ( struct net_device *netdev ) {
  */
 void netdev_close ( struct net_device *netdev ) {
 
-	/* Do nothing if device is already closed */
-	if ( ! ( netdev->state & NETDEV_OPEN ) )
+	/* Do nothing if device is already closed or if the device is
+	 * already in the initialization/closing process */
+	if ( ! ( netdev->state & NETDEV_OPEN ) ||
+		( netdev->state & NETDEV_INITIALIZING ) ||
+		( netdev->state & NETDEV_CLOSING ) )
 		return;
 
 	DBGC ( netdev, "NETDEV %s closing\n", netdev->name );
 
+	/* Mark as closing */
+	netdev->state |= NETDEV_CLOSING;
+
 	/* Remove from open devices list */
 	list_del ( &netdev->open_list );
 
@@ -550,6 +565,9 @@ void netdev_close ( struct net_device *netdev ) {
 	/* Flush TX and RX queues */
 	netdev_tx_flush ( netdev );
 	netdev_rx_flush ( netdev );
+
+	/* Unmark device as closing*/
+	netdev->state &= ~NETDEV_CLOSING;
 }
 
 /**
@@ -632,7 +650,7 @@ struct net_device * find_netdev_by_location ( unsigned int bus_type,
 			return netdev;
 	}
 
-	return NULL;	
+	return NULL;
 }
 
 /**
-- 
1.7.11.1



More information about the ipxe-devel mailing list