]> xenbits.xensource.com Git - unikraft/libs/lwip.git/commitdiff
init: Option to wait for DHCP RELEASE-0.16.2
authorSimon Kuenzer <simon@unikraft.io>
Fri, 2 Feb 2024 13:16:46 +0000 (14:16 +0100)
committerRazvan Deaconescu <razvan.deaconescu@upb.ro>
Fri, 9 Feb 2024 20:31:10 +0000 (22:31 +0200)
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 <simon@unikraft.io>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
Reviewed-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #47

Config.uk
init.c

index d18ce35b576ba5636642a909582525dd3546afd2..b541695095ac352c10e42415e760b0f15f789cee 100644 (file)
--- 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 763146da5755243817254c8662ddea555a9b2a58..c16a8185f95866a2a65a25c97cc376614f7d5936 100644 (file)
--- a/init.c
+++ b/init.c
 #include "lwip/inet.h"
 #if CONFIG_LWIP_NOTHREADS
 #include "lwip/timeouts.h"
-#else /* CONFIG_LWIP_NOTHREADS */
-#include <uk/semaphore.h>
 #endif /* CONFIG_LWIP_NOTHREADS */
+#if !CONFIG_LWIP_NOTHREADS || CONFIG_LWIP_WAITIFACE
+#include <uk/semaphore.h>
+#endif /* !CONFIG_LWIP_NOTHREADS || CONFIG_LWIP_WAITIFACE */
+#if CONFIG_LWIP_WAITIFACE
+#include <uk/arch/time.h>
+#endif /* CONFIG_LWIP_WAITIFACE */
 #include <errno.h>
 #include <uk/netdev_core.h>
 #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 */