From: Simon Kuenzer Date: Fri, 2 Feb 2024 13:16:46 +0000 (+0100) Subject: init: Option to wait for DHCP X-Git-Tag: RELEASE-0.16.2 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=7c1859a7069701f992dbf0b9508335377f55d364;p=unikraft%2Flibs%2Flwip.git init: Option to wait for DHCP This commit introduces an configuration option to wait for the first network interface to be configured by DHCP. In case one interface is configured with a static IP, the sytem will immediately continue booting. Signed-off-by: Simon Kuenzer Approved-by: Razvan Deaconescu Reviewed-by: Razvan Deaconescu GitHub-Closes: #47 --- diff --git a/Config.uk b/Config.uk index d18ce35..b541695 100644 --- a/Config.uk +++ b/Config.uk @@ -283,6 +283,21 @@ config LWIP_DHCP query the IPv4 addresses for the found devices from a DHCP server on network. +if LWIP_DHCP +config LWIP_WAITIFACE + bool "Wait for 1st interface" + depends on LWIP_AUTOIFACE + select LWIP_NETIF_EXT_STATUS_CALLBACK + select LIBUKLOCK + select LIBUKLOCK_SEMAPHORE + +config LWIP_WAITIFACE_TO + int "Wait timeout (seconds, 0 = forever)" + range 0 300 + default 5 + depends on LWIP_WAITIFACE +endif # LWIP_DHCP + menuconfig LWIP_DNS bool "DNS Resolver" default y diff --git a/init.c b/init.c index 763146d..c16a818 100644 --- a/init.c +++ b/init.c @@ -41,9 +41,13 @@ #include "lwip/inet.h" #if CONFIG_LWIP_NOTHREADS #include "lwip/timeouts.h" -#else /* CONFIG_LWIP_NOTHREADS */ -#include #endif /* CONFIG_LWIP_NOTHREADS */ +#if !CONFIG_LWIP_NOTHREADS || CONFIG_LWIP_WAITIFACE +#include +#endif /* !CONFIG_LWIP_NOTHREADS || CONFIG_LWIP_WAITIFACE */ +#if CONFIG_LWIP_WAITIFACE +#include +#endif /* CONFIG_LWIP_WAITIFACE */ #include #include #include "netif/uknetdev.h" @@ -131,6 +135,14 @@ static void _lwip_init_done(void *arg __unused) static unsigned int lwip_netif_attached = 0; +#if CONFIG_LWIP_WAITIFACE +static struct uk_semaphore _lwip_waitif_sem; +NETIF_DECLARE_EXT_CALLBACK(lwip_netif_waitif); + +static void _lwip_netif_waitif(struct netif *nf, netif_nsc_reason_t reason, + const netif_ext_callback_args_t *args); +#endif /* CONFIG_LWIP_WAITIFACE */ + /* * This function initializing the lwip network stack */ @@ -163,6 +175,9 @@ static int liblwip_init(struct uk_init_ctx *ictx __unused) #if !CONFIG_LWIP_NOTHREADS uk_semaphore_init(&_lwip_init_sem, 0); #endif /* !CONFIG_LWIP_NOTHREADS */ +#if CONFIG_LWIP_WAITIFACE + uk_semaphore_init(&_lwip_waitif_sem, 0); +#endif /* CONFIG_LWIP_WAITIFACE */ #if CONFIG_LWIP_NOTHREADS lwip_init(); @@ -177,6 +192,9 @@ static int liblwip_init(struct uk_init_ctx *ictx __unused) /* Add print callback for netif state changes */ netif_add_ext_callback(&netif_status_print, _netif_status_print); #endif /* LWIP_NETIF_EXT_STATUS_CALLBACK && CONFIG_LWIP_NETIF_STATUS_PRINT */ +#if CONFIG_LWIP_WAITIFACE + netif_add_ext_callback(&lwip_netif_waitif, _lwip_netif_waitif); +#endif /* CONFIG_LWIP_WAITIFACE */ #if CONFIG_LWIP_UKNETDEV && CONFIG_LWIP_AUTOIFACE is_first_nf = 1; @@ -445,3 +463,59 @@ static void liblwip_term(const struct uk_term_ctx *tctx __unused) } uk_lib_initcall(liblwip_init, liblwip_term); + +#if CONFIG_LWIP_WAITIFACE +static void _lwip_netif_waitif(struct netif *nf, netif_nsc_reason_t reason, + const netif_ext_callback_args_t *args) +{ + if (0x0 +#if LWIP_IPV4 + || (reason & LWIP_NSC_IPV4_SETTINGS_CHANGED) + || (reason & LWIP_NSC_IPV4_ADDRESS_CHANGED) +#endif /* LWIP_IPV4 */ +#if LWIP_IPV6 + || (reason & LWIP_NSC_IPV6_SET) + || (reason & LWIP_NSC_IPV6_ADDR_STATE_CHANGED) +#endif /* LWIP_IPV6 */ + ) { + uk_semaphore_up(&_lwip_waitif_sem); + } +} + +static int liblwip_waitif(struct uk_init_ctx *ictx __unused) +{ +#if CONFIG_LWIP_WAITIFACE_TO + int lefttime = CONFIG_LWIP_WAITIFACE_TO; +#endif /* CONFIG_LWIP_WAITIFACE_TO */ + + if (lwip_netif_attached == 0) + return 0; /* No interface to wait for */ + if (uk_semaphore_down_try(&_lwip_waitif_sem) > 0) + return 0; /* Fast path: at least one netif is already + * configured (probably a static IP) --> + * Do not print, continue booting. + */ + + uk_pr_info("Wait for networking..."); + while (uk_semaphore_down_to(&_lwip_waitif_sem, + ukarch_time_sec_to_nsec(1)) == __NSEC_MAX) { +#if CONFIG_LWIP_WAITIFACE_TO + lefttime--; + if (lefttime == 0) { +#if !LWIP_FAILNOIFACE + uk_pr_info("Timed out\n"); + return 0; +#else /* LWIP_FAILNOIFACE */ + uk_pr_crit("Network setup timed out\n"); + return -ETIMEDOUT; +#endif /* LWIP_FAILNOIFACE */ + } +#endif /* CONFIG_LWIP_WAITIFACE_TO */ + uk_pr_info("."); + } + uk_pr_info("\n"); + return 0; +} + +uk_late_initcall_prio(liblwip_waitif, 0x0, UK_PRIO_LATEST); +#endif /* CONFIG_LWIP_WAITIFACE */