From 26b87b221b45ccf53257962f4de030fbe855d634 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Mon, 4 Nov 2013 17:05:53 +0000 Subject: [ifmgmt] Add ifconf() to carry out network device configuration Signed-off-by: Michael Brown --- src/usr/ifmgmt.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 87 insertions(+), 2 deletions(-) (limited to 'src/usr') 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 #include #include +#include #include /** @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 ); } -- cgit v1.2.3-55-g7522