[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 UTC 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