From e3c7a1948d080a753aceb92c8bfed07dfdf3daac Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Sat, 31 Jul 2010 09:20:41 +0100 Subject: [PATCH] [dhcp] Allow multiple interfaces in dhcp command The "dhcp" command now accepts a list of interfaces to try until one succeeds. For example: iPXE> dhcp net0 net1 net2 If no interfaces are specified, all interfaces will be tried. Note that interfaces that fail to DHCP are closed in order to avoid memory exhaustion. This behavior differs from the previous "dhcp" command implementation but should not affect any existing scripts since a "dhcp" command failure would in any case cause the script to abort. Originally-implemented-by: Lars Kellogg-Stedman Signed-off-by: Michael Brown --- src/hci/commands/dhcp_cmd.c | 78 ++++++++++++++++++++++++++----------- 1 file changed, 56 insertions(+), 22 deletions(-) diff --git a/src/hci/commands/dhcp_cmd.c b/src/hci/commands/dhcp_cmd.c index 82869d62..6da0d637 100644 --- a/src/hci/commands/dhcp_cmd.c +++ b/src/hci/commands/dhcp_cmd.c @@ -45,12 +45,52 @@ FILE_LICENCE ( GPL2_OR_LATER ); */ static void dhcp_syntax ( char **argv ) { printf ( "Usage:\n" - " %s \n" + " %s [] [...]\n" "\n" "Configure a network interface using DHCP\n", argv[0] ); } +/** + * Execute "dhcp" command for a network device + * + * @v netdev Network device + * @ret rc Exit code + */ +static int dhcp_exec_netdev ( struct net_device *netdev ) { + int rc; + + if ( ( rc = dhcp ( netdev ) ) != 0 ) { + printf ( "Could not configure %s: %s\n", + netdev->name, strerror ( rc ) ); + + /* Close device on failure, to avoid memory exhaustion */ + netdev_close ( netdev ); + + return 1; + } + + return 0; +} + +/** + * Execute "dhcp" command for a named network device + * + * @v netdev_name Network device name + * @ret rc Exit code + */ +static int dhcp_exec_name ( const char *netdev_name ) { + struct net_device *netdev; + + netdev = find_netdev ( netdev_name ); + if ( ! netdev ) { + printf ( "No such interface \"%s\"\n", netdev_name ); + return 1; + } + + return dhcp_exec_netdev ( netdev ); +} + /** * The "dhcp" command * @@ -63,7 +103,7 @@ static int dhcp_exec ( int argc, char **argv ) { { "help", 0, NULL, 'h' }, { NULL, 0, NULL, 0 }, }; - const char *netdev_txt; + const char *netdev_name; struct net_device *netdev; int c; int rc; @@ -80,28 +120,22 @@ static int dhcp_exec ( int argc, char **argv ) { } } - /* Need exactly one interface name remaining after the options */ - if ( optind != ( argc - 1 ) ) { - dhcp_syntax ( argv ); - return 1; - } - netdev_txt = argv[optind]; - - /* Parse arguments */ - netdev = find_netdev ( netdev_txt ); - if ( ! netdev ) { - printf ( "No such interface: %s\n", netdev_txt ); - return 1; + if ( optind != argc ) { + /* Treat arguments as a list of interfaces to try */ + while ( optind != argc ) { + netdev_name = argv[optind++]; + if ( ( rc = dhcp_exec_name ( netdev_name ) ) == 0 ) + return 0; + } + } else { + /* Try all interfaces */ + for_each_netdev ( netdev ) { + if ( ( rc = dhcp_exec_netdev ( netdev ) ) == 0 ) + return 0; + } } - /* Perform DHCP */ - if ( ( rc = dhcp ( netdev ) ) != 0 ) { - printf ( "Could not configure %s: %s\n", netdev->name, - strerror ( rc ) ); - return 1; - } - - return 0; + return 1; } /**