[rndis] Clean up error handling path in register_rndis()

Avoid calling rndis_halt() and rndis->op->close() twice if the call to
register_netdev() fails.

Reported-by: Roman Kagan <rkagan@virtuozzo.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
pull/76/head
Michael Brown 2018-07-09 10:35:57 +01:00
parent 1c47eb186e
commit 05b979146d
1 changed files with 61 additions and 41 deletions

View File

@ -650,6 +650,63 @@ static int rndis_oid ( struct rndis_device *rndis, unsigned int oid,
return 0;
}
/**
* Describe RNDIS device
*
* @v rndis RNDIS device
* @ret rc Return status code
*/
static int rndis_describe ( struct rndis_device *rndis ) {
struct net_device *netdev = rndis->netdev;
int rc;
/* Assign device name (for debugging) */
rndis->name = netdev->dev->name;
/* Open RNDIS device to read MAC addresses */
if ( ( rc = rndis->op->open ( rndis ) ) != 0 ) {
DBGC ( rndis, "RNDIS %s could not open: %s\n",
rndis->name, strerror ( rc ) );
goto err_open;
}
/* Initialise RNDIS */
if ( ( rc = rndis_initialise ( rndis ) ) != 0 )
goto err_initialise;
/* Query permanent MAC address */
if ( ( rc = rndis_oid ( rndis, RNDIS_OID_802_3_PERMANENT_ADDRESS,
NULL, 0 ) ) != 0 )
goto err_query_permanent;
/* Query current MAC address */
if ( ( rc = rndis_oid ( rndis, RNDIS_OID_802_3_CURRENT_ADDRESS,
NULL, 0 ) ) != 0 )
goto err_query_current;
/* Get link status */
if ( ( rc = rndis_oid ( rndis, RNDIS_OID_GEN_MEDIA_CONNECT_STATUS,
NULL, 0 ) ) != 0 )
goto err_query_link;
/* Halt RNDIS device */
rndis_halt ( rndis );
/* Close RNDIS device */
rndis->op->close ( rndis );
return 0;
err_query_link:
err_query_current:
err_query_permanent:
rndis_halt ( rndis );
err_initialise:
rndis->op->close ( rndis );
err_open:
return rc;
}
/**
* Receive indicate status message
*
@ -970,40 +1027,9 @@ int register_rndis ( struct rndis_device *rndis ) {
struct net_device *netdev = rndis->netdev;
int rc;
/* Assign device name (for debugging) */
rndis->name = netdev->dev->name;
/* Open RNDIS device to read MAC addresses */
if ( ( rc = rndis->op->open ( rndis ) ) != 0 ) {
DBGC ( rndis, "RNDIS %s could not open: %s\n",
rndis->name, strerror ( rc ) );
goto err_open;
}
/* Initialise RNDIS */
if ( ( rc = rndis_initialise ( rndis ) ) != 0 )
goto err_initialise;
/* Query permanent MAC address */
if ( ( rc = rndis_oid ( rndis, RNDIS_OID_802_3_PERMANENT_ADDRESS,
NULL, 0 ) ) != 0 )
goto err_query_permanent;
/* Query current MAC address */
if ( ( rc = rndis_oid ( rndis, RNDIS_OID_802_3_CURRENT_ADDRESS,
NULL, 0 ) ) != 0 )
goto err_query_current;
/* Get link status */
if ( ( rc = rndis_oid ( rndis, RNDIS_OID_GEN_MEDIA_CONNECT_STATUS,
NULL, 0 ) ) != 0 )
goto err_query_link;
/* Halt RNDIS device */
rndis_halt ( rndis );
/* Close RNDIS device */
rndis->op->close ( rndis );
/* Describe RNDIS device */
if ( ( rc = rndis_describe ( rndis ) ) != 0 )
goto err_describe;
/* Register network device */
if ( ( rc = register_netdev ( netdev ) ) != 0 ) {
@ -1016,13 +1042,7 @@ int register_rndis ( struct rndis_device *rndis ) {
unregister_netdev ( netdev );
err_register:
err_query_link:
err_query_current:
err_query_permanent:
rndis_halt ( rndis );
err_initialise:
rndis->op->close ( rndis );
err_open:
err_describe:
return rc;
}