summaryrefslogtreecommitdiffstats
path: root/src/usr
diff options
context:
space:
mode:
authorMichael Brown2013-11-04 18:05:53 +0100
committerMichael Brown2013-11-05 18:30:20 +0100
commit26b87b221b45ccf53257962f4de030fbe855d634 (patch)
tree09e4d8e0b3b2d205ec7faa15c41677e81e0279ea /src/usr
parent[parseopt] Add parse_netdev_configurator() (diff)
downloadipxe-26b87b221b45ccf53257962f4de030fbe855d634.tar.gz
ipxe-26b87b221b45ccf53257962f4de030fbe855d634.tar.xz
ipxe-26b87b221b45ccf53257962f4de030fbe855d634.zip
[ifmgmt] Add ifconf() to carry out network device configuration
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/usr')
-rw-r--r--src/usr/ifmgmt.c89
1 files changed, 87 insertions, 2 deletions
diff --git a/src/usr/ifmgmt.c b/src/usr/ifmgmt.c
index cf7e6b6a..cab1cd91 100644
--- a/src/usr/ifmgmt.c
+++ b/src/usr/ifmgmt.c
@@ -29,6 +29,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <ipxe/job.h>
#include <ipxe/monojob.h>
#include <ipxe/nap.h>
+#include <ipxe/timer.h>
#include <usr/ifmgmt.h>
/** @file
@@ -37,6 +38,15 @@ FILE_LICENCE ( GPL2_OR_LATER );
*
*/
+/** Default time to wait for link-up */
+#define LINK_WAIT_TIMEOUT ( 15 * TICKS_PER_SEC )
+
+/** Default unsuccessful configuration status code */
+#define EADDRNOTAVAIL_CONFIG __einfo_error ( EINFO_EADDRNOTAVAIL_CONFIG )
+#define EINFO_EADDRNOTAVAIL_CONFIG \
+ __einfo_uniqify ( EINFO_EADDRNOTAVAIL, 0x01, \
+ "No configuration methods succeeded" )
+
/**
* Open network device
*
@@ -111,6 +121,8 @@ struct ifpoller {
struct interface job;
/** Network device */
struct net_device *netdev;
+ /** Network device configurator (if applicable) */
+ struct net_device_configurator *configurator;
/**
* Check progress
*
@@ -150,17 +162,21 @@ static struct interface_descriptor ifpoller_job_desc =
* Poll network device until completion
*
* @v netdev Network device
+ * @v configurator Network device configurator (if applicable)
* @v timeout Timeout period, in ticks
* @v progress Method to check progress
* @ret rc Return status code
*/
-static int ifpoller_wait ( struct net_device *netdev, unsigned long timeout,
+static int ifpoller_wait ( struct net_device *netdev,
+ struct net_device_configurator *configurator,
+ unsigned long timeout,
int ( * progress ) ( struct ifpoller *ifpoller ) ) {
static struct ifpoller ifpoller = {
.job = INTF_INIT ( ifpoller_job_desc ),
};
ifpoller.netdev = netdev;
+ ifpoller.configurator = configurator;
ifpoller.progress = progress;
intf_plug_plug ( &monojob, &ifpoller.job );
return monojob_wait ( "", timeout );
@@ -204,5 +220,74 @@ int iflinkwait ( struct net_device *netdev, unsigned long timeout ) {
/* Wait for link-up */
printf ( "Waiting for link-up on %s", netdev->name );
- return ifpoller_wait ( netdev, timeout, iflinkwait_progress );
+ return ifpoller_wait ( netdev, NULL, timeout, iflinkwait_progress );
+}
+
+/**
+ * Check configuration progress
+ *
+ * @v ifpoller Network device poller
+ * @ret ongoing_rc Ongoing job status code (if known)
+ */
+static int ifconf_progress ( struct ifpoller *ifpoller ) {
+ struct net_device *netdev = ifpoller->netdev;
+ struct net_device_configurator *configurator = ifpoller->configurator;
+ struct net_device_configuration *config;
+ int rc;
+
+ /* Do nothing unless configuration has completed */
+ if ( netdev_configuration_in_progress ( netdev ) )
+ return 0;
+
+ /* Terminate with appropriate overall return status code */
+ if ( configurator ) {
+ config = netdev_configuration ( netdev, configurator );
+ rc = config->rc;
+ } else {
+ rc = ( netdev_configuration_ok ( netdev ) ?
+ 0 : -EADDRNOTAVAIL_CONFIG );
+ }
+ intf_close ( &ifpoller->job, rc );
+
+ return rc;
+}
+
+/**
+ * Perform network device configuration
+ *
+ * @v netdev Network device
+ * @v configurator Network device configurator, or NULL to use all
+ * @ret rc Return status code
+ */
+int ifconf ( struct net_device *netdev,
+ struct net_device_configurator *configurator ) {
+ int rc;
+
+ /* Ensure device is open and link is up */
+ if ( ( rc = iflinkwait ( netdev, LINK_WAIT_TIMEOUT ) ) != 0 )
+ return rc;
+
+ /* Start configuration */
+ if ( configurator ) {
+ if ( ( rc = netdev_configure ( netdev, configurator ) ) != 0 ) {
+ printf ( "Could not configure %s via %s: %s\n",
+ netdev->name, configurator->name,
+ strerror ( rc ) );
+ return rc;
+ }
+ } else {
+ if ( ( rc = netdev_configure_all ( netdev ) ) != 0 ) {
+ printf ( "Could not configure %s: %s\n",
+ netdev->name, strerror ( rc ) );
+ return rc;
+ }
+ }
+
+ /* Wait for configuration to complete */
+ printf ( "Configuring %s%s%s(%s %s)",
+ ( configurator ? "[" : "" ),
+ ( configurator ? configurator->name : "" ),
+ ( configurator ? "] " : "" ),
+ netdev->name, netdev->ll_protocol->ntoa ( netdev->ll_addr ) );
+ return ifpoller_wait ( netdev, configurator, 0, ifconf_progress );
}