Description: Many fixes on the POSIX library
Forwarded: https://savannah.nongnu.org/patch/?10536
Author: Joan Lledó <jlledom@member.fsf.org>
Last-Update: 2024-01-13

Index: lwip-deb/contrib/ports/unix/posixlib/CMakeLists.txt
===================================================================
--- lwip-deb.orig/contrib/ports/unix/posixlib/CMakeLists.txt	2026-04-02 14:19:43.000000000 +0200
+++ lwip-deb/contrib/ports/unix/posixlib/CMakeLists.txt	2026-04-02 14:35:03.000000000 +0200
@@ -1,8 +1,8 @@
 cmake_minimum_required(VERSION 3.8)
 project(liblwip
     VERSION 2.2.0
-    DESCRIPTION "lwip library for linux"
-    HOMEPAGE_URL "http://wiki.virtualsquare.org"
+    DESCRIPTION "lwip library for POSIX systems"
+    HOMEPAGE_URL "https://savannah.nongnu.org/projects/lwip/"
     LANGUAGES C)
 
 include(GNUInstallDirs)
@@ -10,7 +10,7 @@
 
 set (BUILD_SHARED_LIBS ON)
 
-if (NOT CMAKE_SYSTEM_NAME STREQUAL "Linux")
+if (NOT CMAKE_SYSTEM_NAME STREQUAL "Linux" AND NOT CMAKE_SYSTEM_NAME STREQUAL "GNU")
     message(FATAL_ERROR "Lwip shared library is only working on Linux or the Hurd")
 endif()
 
@@ -39,10 +39,13 @@
 include(${LWIP_CONTRIB_DIR}/ports/unix/Filelists.cmake)
 include(${LWIP_DIR}/src/Filelists.cmake)
 if (LIB_VDEPLUGOK AND INCLUDE_VDEPLUGOK)
-set(lwipnoapps_SRCS ${lwipnoapps_SRCS}
+set(lwipcontribportunixnetifs_SRCS ${lwipcontribportunixnetifs_SRCS}
    ${LWIP_DIR}/contrib/ports/unix/port/netif/vdeif.c)
 endif()
 
+set(lwipcontribportunix_SRCS ${lwipcontribportunix_SRCS}
+   ${LWIP_DIR}/contrib/ports/unix/posixlib/lwip_hooks.c)
+
 add_library(lwip ${lwipnoapps_SRCS} ${lwipcontribportunix_SRCS} ${lwipcontribportunixnetifs_SRCS})
 target_compile_options(lwip PRIVATE ${LWIP_COMPILER_FLAGS})
 target_compile_definitions(lwip PRIVATE ${LWIP_DEFINITIONS} ${LWIP_MBEDTLS_DEFINITIONS})
@@ -56,7 +59,15 @@
 find_library(LIBPTHREAD pthread)
 target_link_libraries(lwip ${LIBPTHREAD})
 
-install(TARGETS lwip 
+include(${LWIP_DIR}/src/Filelists.cmake)
+if (TARGET lwipdocs)
+  add_dependencies(lwip lwipdocs)
+endif()
+
+# Generate pkg-config file
+CONFIGURE_FILE("${LWIP_CONTRIB_DIR}/ports/unix/posixlib/lwip.pc.in" "${LWIP_CONTRIB_DIR}/ports/unix/posixlib/lwip.pc" @ONLY)
+
+install(TARGETS lwip
 		LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
 
 set_target_properties(lwip PROPERTIES VERSION ${PROJECT_VERSION}
@@ -89,6 +100,9 @@
     FILES_MATCHING PATTERN "*.h"
 )
 
+install (FILES ${LWIP_CONTRIB_DIR}/ports/unix/posixlib/lwip.pc
+    DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
+
 add_custom_target(uninstall
   "${CMAKE_COMMAND}" -P "${PROJECT_SOURCE_DIR}/Uninstall.cmake")
 
Index: lwip-deb/contrib/ports/unix/posixlib/lwip.pc.in
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ lwip-deb/contrib/ports/unix/posixlib/lwip.pc.in	2026-04-02 14:19:43.000000000 +0200
@@ -0,0 +1,10 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=${prefix}
+libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
+includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@/lwip
+
+Name: liblwip
+Description: LwIP shared library
+Version: @LWIP_VERSION_MAJOR@.@LWIP_VERSION_MINOR@.@LWIP_VERSION_REVISION@
+Libs: -L${libdir} -llwip
+Cflags: -I${includedir}
Index: lwip-deb/contrib/ports/unix/port/sys_arch.c
===================================================================
--- lwip-deb.orig/contrib/ports/unix/port/sys_arch.c	2026-04-02 14:19:43.000000000 +0200
+++ lwip-deb/contrib/ports/unix/port/sys_arch.c	2026-04-02 14:33:54.000000000 +0200
@@ -73,9 +73,6 @@
 static pthread_key_t sys_thread_sem_key;
 #endif
 
-/* Return code for an interrupted timed wait */
-#define SYS_ARCH_INTR 0xfffffffeUL
-
 u32_t
 lwip_port_rand(void)
 {
@@ -414,7 +411,7 @@
 u32_t
 sys_arch_mbox_fetch(struct sys_mbox **mb, void **msg, u32_t timeout)
 {
-  u32_t time_needed = 0;
+  u32_t ret = 0;
   struct sys_mbox *mbox;
   LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
   mbox = *mb;
@@ -429,9 +426,9 @@
     /* We block while waiting for a mail to arrive in the mailbox. We
        must be prepared to timeout. */
     if (timeout != 0) {
-      time_needed = sys_arch_sem_wait(&mbox->not_empty, timeout);
+      ret = sys_arch_sem_wait(&mbox->not_empty, timeout);
 
-      if (time_needed == SYS_ARCH_TIMEOUT) {
+      if (ret == SYS_ARCH_TIMEOUT) {
         return SYS_ARCH_TIMEOUT;
       }
     } else {
@@ -457,7 +454,7 @@
 
   sys_sem_signal(&mbox->mutex);
 
-  return time_needed;
+  return ret;
 }
 
 /*-----------------------------------------------------------------------------------*/
@@ -494,7 +491,7 @@
 static u32_t
 cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex, u32_t timeout)
 {
-  struct timespec rtime1, rtime2, ts;
+  struct timespec rtime1, ts;
   int ret;
 
 #ifdef LWIP_UNIX_HURD
@@ -529,60 +526,59 @@
 
   ret = pthread_cond_timedwait(cond, mutex, &ts);
 #endif
-  if (ret == ETIMEDOUT) {
+  if (ret == ETIMEDOUT)
     return SYS_ARCH_TIMEOUT;
 #ifdef LWIP_UNIX_HURD
-    /* On the Hurd, ret == 1 means the RPC has been cancelled.
-     * The thread is awakened (not terminated) and execution must continue */
-  } else if (ret == EINTR) {
+  /* On the Hurd, ret == EINTR means the RPC has been canceled.
+   * The thread is awakened (not terminated) and execution must continue */
+  if (ret == EINTR)
     return SYS_ARCH_INTR;
 #endif
-  }
 
-  /* Calculate for how long we waited for the cond. */
-  get_monotonic_time(&rtime2);
-  ts.tv_sec = rtime2.tv_sec - rtime1.tv_sec;
-  ts.tv_nsec = rtime2.tv_nsec - rtime1.tv_nsec;
-  if (ts.tv_nsec < 0) {
-    ts.tv_sec--;
-    ts.tv_nsec += 1000000000L;
-  }
-  return (u32_t)(ts.tv_sec * 1000L + ts.tv_nsec / 1000000L);
+  return ret;
 }
 
+static
 u32_t
-sys_arch_sem_wait(struct sys_sem **s, u32_t timeout)
+sys_arch_sem_wait_internal(struct sys_sem **s, u32_t timeout, u8_t interruptible)
 {
-  u32_t time_needed = 0;
+  u32_t ret = 0;
   struct sys_sem *sem;
   LWIP_ASSERT("invalid sem", (s != NULL) && (*s != NULL));
   sem = *s;
 
   pthread_mutex_lock(&(sem->mutex));
   while (sem->c <= 0) {
-    if (timeout > 0) {
-      time_needed = cond_wait(&(sem->cond), &(sem->mutex), timeout);
+    ret = cond_wait(&(sem->cond), &(sem->mutex), timeout);
 
-      if (time_needed == SYS_ARCH_TIMEOUT) {
-        pthread_mutex_unlock(&(sem->mutex));
-        return SYS_ARCH_TIMEOUT;
-#ifdef LWIP_UNIX_HURD
-      } else if(time_needed == SYS_ARCH_INTR) {
-        pthread_mutex_unlock(&(sem->mutex));
-        return 0;
-#endif
-      }
-      /*      pthread_mutex_unlock(&(sem->mutex));
-              return time_needed; */
-    } else if(cond_wait(&(sem->cond), &(sem->mutex), 0)) {
-      /* Some error happened or the thread has been awakened but not by lwip */
+    if (ret == SYS_ARCH_TIMEOUT) {
+      pthread_mutex_unlock(&(sem->mutex));
+      return ret;
+    }
+
+    if (interruptible && ret == SYS_ARCH_INTR) {
       pthread_mutex_unlock(&(sem->mutex));
-      return 0;
+      return ret;
     }
+
+    if (ret != 0)
+      LWIP_DEBUGF(SYS_DEBUG, ("cond_wait error: %s\n", strerror(ret)));
   }
   sem->c--;
   pthread_mutex_unlock(&(sem->mutex));
-  return (u32_t)time_needed;
+  return 0;
+}
+
+u32_t
+sys_arch_sem_wait_interruptible(struct sys_sem **s, u32_t timeout)
+{
+  return sys_arch_sem_wait_internal(s, timeout, 1);
+}
+
+u32_t
+sys_arch_sem_wait(struct sys_sem **s, u32_t timeout)
+{
+  return sys_arch_sem_wait_internal(s, timeout, 0);
 }
 
 void
Index: lwip-deb/contrib/ports/unix/posixlib/include/posix/inet.h
===================================================================
--- lwip-deb.orig/contrib/ports/unix/posixlib/include/posix/inet.h	2026-04-02 14:19:43.000000000 +0200
+++ lwip-deb/contrib/ports/unix/posixlib/include/posix/inet.h	2026-04-02 14:19:43.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 Joan Lled <jlledom@member.fsf.org>
+ * Copyright (C) 2023 Joan Lledó <jlledom@member.fsf.org>
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
@@ -24,8 +24,8 @@
  * OF SUCH DAMAGE.
  */
 
-#ifndef HURD_LWIP_POSIX_INET_H
-#define HURD_LWIP_POSIX_INET_H
+#ifndef POSIX_LWIP_POSIX_INET_H
+#define POSIX_LWIP_POSIX_INET_H
 
 #include <arpa/inet.h>
 #include <netinet/in.h>
@@ -44,15 +44,6 @@
 #define inet_addr_from_ip4addr(target_inaddr, source_ipaddr) ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr))
 #define inet_addr_to_ip4addr(target_ipaddr, source_inaddr)   (ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr))
 
-#ifdef LWIP_UNIX_HURD
-#define IP_PKTINFO  8
-
-struct in_pktinfo {
-  unsigned int   ipi_ifindex;  /* Interface index */
-  struct in_addr ipi_addr;     /* Destination (from header) address */
-};
-#endif /* LWIP_UNIX_HURD */
-
 #endif /* LWIP_IPV4 */
 
 #if LWIP_IPV6
@@ -73,4 +64,4 @@
 }
 #endif
 
-#endif /* HURD_LWIP_POSIX_INET_H */
+#endif /* POSIX_LWIP_POSIX_INET_H */
Index: lwip-deb/contrib/ports/unix/posixlib/include/posix/sockets.h
===================================================================
--- lwip-deb.orig/contrib/ports/unix/posixlib/include/posix/sockets.h	2026-04-02 14:19:43.000000000 +0200
+++ lwip-deb/contrib/ports/unix/posixlib/include/posix/sockets.h	2026-04-02 14:19:43.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 Joan Lled <jlledom@member.fsf.org>
+ * Copyright (C) 2023 Joan Lledó <jlledom@member.fsf.org>
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
@@ -24,40 +24,36 @@
  * OF SUCH DAMAGE.
  */
 
-#ifndef HURD_LWIP_POSIX_SOCKET_H
-#define HURD_LWIP_POSIX_SOCKET_H
+#ifndef POSIX_LWIP_POSIX_SOCKET_H
+#define POSIX_LWIP_POSIX_SOCKET_H
 
 #include <sys/socket.h>
 #include <poll.h>
 #include <errno.h>
 #include LWIP_SOCKET_EXTERNAL_HEADER_INET_H
+
+#ifdef LWIP_UNIX_HURD
+typedef int msg_iovlen_t;
+#else
 typedef size_t msg_iovlen_t;
+#endif /* LWIP_UNIX_HURD */
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 #ifdef _HAVE_SA_LEN
-#define HAVE_SA_LEN	_HAVE_SA_LEN
+#define LWIP_SOCKET_HAVE_SA_LEN     _HAVE_SA_LEN
 #else
-#define HAVE_SA_LEN	0
+#define LWIP_SOCKET_HAVE_SA_LEN     0
 #endif /* _HAVE_SA_LEN */
 
-/* Address length safe read and write */
-#if HAVE_SA_LEN
-#define IP4ADDR_SOCKADDR_SET_LEN(sin) \
-      (sin)->sin_len = sizeof(struct sockaddr_in)
-#define IP6ADDR_SOCKADDR_SET_LEN(sin6) \
-      (sin6)->sin6_len = sizeof(struct sockaddr_in6)
-#define IPADDR_SOCKADDR_GET_LEN(addr) \
-      (addr)->sa.sa_len
+/* struct in_pktinfo includes ipi_spec_dst in Linux and the Hurd */
+#if defined(LWIP_UNIX_LINUX) || defined(LWIP_UNIX_HURD)
+#define LWIP_SOCKET_HAVE_IPI_SPEC_DST   1
 #else
-#define IP4ADDR_SOCKADDR_SET_LEN(addr)
-#define IP6ADDR_SOCKADDR_SET_LEN(addr)
-#define IPADDR_SOCKADDR_GET_LEN(addr) \
-      ((addr)->sa.sa_family == AF_INET ? sizeof(struct sockaddr_in) \
-        : ((addr)->sa.sa_family == AF_INET6 ? sizeof(struct sockaddr_in6) : 0))
-#endif /* HAVE_SA_LEN */
+#define LWIP_SOCKET_HAVE_IPI_SPEC_DST   0
+#endif
 
 #define SIN_ZERO_LEN	sizeof (struct sockaddr) - \
                            __SOCKADDR_COMMON_SIZE - \
@@ -147,4 +143,4 @@
 }
 #endif
 
-#endif /* HURD_LWIP_POSIX_SOCKET_H */
+#endif /* POSIX_LWIP_POSIX_SOCKET_H */
Index: lwip-deb/contrib/ports/unix/posixlib/lwipopts.h
===================================================================
--- lwip-deb.orig/contrib/ports/unix/posixlib/lwipopts.h	2026-04-02 14:19:43.000000000 +0200
+++ lwip-deb/contrib/ports/unix/posixlib/lwipopts.h	2026-04-02 14:36:20.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 Joan Lled <jlledom@member.fsf.org>
+ * Copyright (C) 2023 Joan Lledó <jlledom@member.fsf.org>
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
@@ -24,8 +24,8 @@
  * OF SUCH DAMAGE.
  */
 
-#ifndef UNIX_LWIP_LWIPOPTS_H
-#define UNIX_LWIP_LWIPOPTS_H
+#ifndef POSIX_LWIP_LWIPOPTS_H
+#define POSIX_LWIP_LWIPOPTS_H
 
 /* An OS is present */
 #define NO_SYS    0
@@ -33,13 +33,11 @@
 /* Sockets API config */
 #define LWIP_COMPAT_SOCKETS       0
 #define LWIP_SOCKET_OFFSET        1
-#define LWIP_POLL                 1
 
 /* User posix socket headers */
 #define LWIP_SOCKET_EXTERNAL_HEADERS            1
 #define LWIP_SOCKET_EXTERNAL_HEADER_SOCKETS_H   "posix/sockets.h"
 #define LWIP_SOCKET_EXTERNAL_HEADER_INET_H      "posix/inet.h"
-#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS   1
 
 /* Use Glibc malloc()/free() */
 #define MEM_LIBC_MALLOC   1
@@ -97,6 +95,7 @@
 #define LWIP_SO_LINGER              1
 #define SO_REUSE                    1
 #define LWIP_MULTICAST_TX_OPTIONS   1
+#define LWIP_NETBUF_RECVINFO        1
 
 /* Enable modules */
 #define LWIP_ARP              1
@@ -112,6 +111,11 @@
 #define LWIP_ICMP6            1
 #define LWIP_IPV6_MLD         1
 
+/* Let DHCP packets pass through unconfigured interfaces */
+#define LWIP_HOOK_FILENAME "lwip_hooks.h"
+#define LWIP_HOOK_IP4_ROUTE_SRC dhcp_ip4_route_src
+#define LWIP_IP_ACCEPT_UDP_PORT(dst_port) ((dst_port) == PP_NTOHS(LWIP_IANA_PORT_DHCP_SERVER) || (dst_port) == PP_NTOHS(LWIP_IANA_PORT_DHCP_CLIENT))
+
 /* Don't abort the whole stack when an error is detected */
 #define LWIP_NOASSERT_ON_ERROR   1
 
@@ -177,4 +181,4 @@
 #define IP6_DEBUG         LWIP_DBG_OFF
 #endif
 
-#endif /* UNIX_LWIP_LWIPOPTS_H */
+#endif /* POSIX_LWIP_LWIPOPTS_H */
Index: lwip-deb/src/include/lwip/sys.h
===================================================================
--- lwip-deb.orig/src/include/lwip/sys.h	2026-04-02 14:19:43.000000000 +0200
+++ lwip-deb/src/include/lwip/sys.h	2026-04-02 14:19:43.000000000 +0200
@@ -53,7 +53,9 @@
 
 #define sys_sem_new(s, c) ERR_OK
 #define sys_sem_signal(s)
+#define sys_sem_wait_interruptible(s)
 #define sys_sem_wait(s)
+#define sys_arch_sem_wait_interruptible(s)
 #define sys_arch_sem_wait(s,t)
 #define sys_sem_free(s)
 #define sys_sem_valid(s) 0
@@ -86,6 +88,9 @@
 /** Return code for timeouts from sys_arch_mbox_fetch and sys_arch_sem_wait */
 #define SYS_ARCH_TIMEOUT 0xffffffffUL
 
+/** Return code for an interruptions from sys_arch_sem_wait_interruptible */
+#define SYS_ARCH_INTR 0xfffffffeUL
+
 /** sys_mbox_tryfetch() returns SYS_MBOX_EMPTY if appropriate.
  * For now we use the same magic value, but we allow this to change in future.
  */
@@ -206,6 +211,25 @@
  * specified time (measured in milliseconds). If the "timeout" argument is zero,
  * the thread should be blocked until the semaphore is signalled.
  *
+ * The return values are:
+ *   - SYS_ARCH_TIMEOUT if the semaphore wasn't signaled within the given time
+ *   - SYS_ARCH_INTR if the resource gets interrupted externally
+ *   - any other value if it was signaled (with or without waiting).
+ *
+ * @param sem the semaphore to wait for
+ * @param timeout timeout in milliseconds to wait (0 = wait forever)
+ * @return SYS_ARCH_TIMEOUT on timeout
+ *         SYS_ARCH_INTR when getting interrupted
+ *         any other value on success
+ */
+u32_t sys_arch_sem_wait_interruptible(sys_sem_t *sem, u32_t timeout);
+/**
+ * @ingroup sys_sem
+ *  Blocks the thread while waiting for the semaphore to be signaled. If the
+ * "timeout" argument is non-zero, the thread should only be blocked for the
+ * specified time (measured in milliseconds). If the "timeout" argument is zero,
+ * the thread should be blocked until the semaphore is signalled.
+ *
  * The return value is SYS_ARCH_TIMEOUT if the semaphore wasn't signaled within
  * the specified time or any other value if it was signaled (with or without
  * waiting).
@@ -224,6 +248,7 @@
  */
 void sys_sem_free(sys_sem_t *sem);
 /** Wait for a semaphore - forever/no timeout */
+#define sys_sem_wait_interruptible(sem)    sys_arch_sem_wait_interruptible(sem, 0)
 #define sys_sem_wait(sem)                  sys_arch_sem_wait(sem, 0)
 #ifndef sys_sem_valid
 /**
Index: lwip-deb/src/api/sockets.c
===================================================================
--- lwip-deb.orig/src/api/sockets.c	2026-04-02 14:19:43.000000000 +0200
+++ lwip-deb/src/api/sockets.c	2026-04-02 14:36:20.000000000 +0200
@@ -2130,7 +2130,7 @@
             }
           }
 
-          waitres = sys_arch_sem_wait(SELECT_SEM_PTR(API_SELECT_CB_VAR_REF(select_cb).sem), msectimeout);
+          waitres = sys_arch_sem_wait_interruptible(SELECT_SEM_PTR(API_SELECT_CB_VAR_REF(select_cb).sem), msectimeout);
 #if LWIP_NETCONN_SEM_PER_THREAD
           waited = 1;
 #endif
@@ -2174,6 +2174,14 @@
 #endif /* LWIP_NETCONN_SEM_PER_THREAD */
       API_SELECT_CB_VAR_FREE(select_cb);
 
+      if (waitres == SYS_ARCH_INTR) {
+        /* Signaled */
+        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: interrupted\n"));
+        lwip_select_dec_sockets_used(maxfdp1, &used_sockets);
+        set_errno(EINTR);
+        return -1;
+      }
+
       if (nready < 0) {
         /* This happens when a socket got closed while waiting */
         lwip_select_dec_sockets_used(maxfdp1, &used_sockets);
@@ -2435,7 +2443,7 @@
         LWIP_ASSERT("timeout > 0", timeout > 0);
         msectimeout = timeout;
       }
-      waitres = sys_arch_sem_wait(SELECT_SEM_PTR(API_SELECT_CB_VAR_REF(select_cb).sem), msectimeout);
+      waitres = sys_arch_sem_wait_interruptible(SELECT_SEM_PTR(API_SELECT_CB_VAR_REF(select_cb).sem), msectimeout);
 #if LWIP_NETCONN_SEM_PER_THREAD
       waited = 1;
 #endif
@@ -2457,6 +2465,14 @@
 #endif /* LWIP_NETCONN_SEM_PER_THREAD */
     API_SELECT_CB_VAR_FREE(select_cb);
 
+    if (waitres == SYS_ARCH_INTR) {
+      /* Signaled */
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_poll: interrupted\n"));
+      lwip_poll_dec_sockets_used(fds, nfds);
+      set_errno(EINTR);
+      return -1;
+    }
+
     if (nready < 0) {
       /* This happens when a socket got closed while waiting */
       lwip_poll_dec_sockets_used(fds, nfds);
Index: lwip-deb/contrib/ports/unix/port/include/arch/cc.h
===================================================================
--- lwip-deb.orig/contrib/ports/unix/port/include/arch/cc.h	2026-04-02 14:19:43.000000000 +0200
+++ lwip-deb/contrib/ports/unix/port/include/arch/cc.h	2026-04-02 14:19:43.000000000 +0200
@@ -43,8 +43,6 @@
 #define LWIP_UNIX_OPENBSD
 #elif defined __FreeBSD__
 #define LWIP_UNIX_FREEBSD
-#elif defined __FreeBSD_kernel__ && __GLIBC__
-#define LWIP_UNIX_KFREEBSD
 #elif defined __CYGWIN__
 #define LWIP_UNIX_CYGWIN
 #elif defined __GNU__
@@ -60,7 +58,7 @@
 
 #define LWIP_ERRNO_INCLUDE <errno.h>
 
-#if defined(LWIP_UNIX_LINUX) || defined(LWIP_UNIX_HURD) || defined(LWIP_UNIX_KFREEBSD)
+#if defined(LWIP_UNIX_LINUX) || defined(LWIP_UNIX_HURD)
 #define LWIP_ERRNO_STDINCLUDE	1
 #endif
 
@@ -77,7 +75,7 @@
 typedef __kernel_fd_set fd_set;
 #endif
 
-#if defined(LWIP_UNIX_MACH)
+#if defined(LWIP_UNIX_MACH) || defined(LWIP_UNIX_LINUX) || defined(LWIP_UNIX_HURD)
 /* sys/types.h and signal.h bring in Darwin byte order macros. pull the
    header here and disable LwIP's version so that apps still can get
    the macros via LwIP headers and use system headers */
Index: lwip-deb/contrib/ports/unix/posixlib/lwip_hooks.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ lwip-deb/contrib/ports/unix/posixlib/lwip_hooks.c	2026-04-02 14:19:43.000000000 +0200
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2025 Joan Lledó <jlledom@member.fsf.org>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_IPV4
+
+#ifdef LWIP_HOOK_FILENAME
+#include LWIP_HOOK_FILENAME
+#endif
+
+/*
+ * Special route hook to ensure dhcp messages pass through unconfigured interfaces
+ */
+struct netif *
+dhcp_ip4_route_src(const ip4_addr_t *src, const ip4_addr_t *dest)
+{
+  struct netif *netif;
+
+  NETIF_FOREACH(netif) {
+    if (ip4_addr_isany(src) && ip4_addr_isbroadcast(dest, netif))
+      return netif;
+  }
+
+  return NULL;
+}
+
+#endif /* LWIP_IPV4 */
Index: lwip-deb/contrib/ports/unix/posixlib/lwip_hooks.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ lwip-deb/contrib/ports/unix/posixlib/lwip_hooks.h	2026-04-02 14:19:43.000000000 +0200
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2025 Joan Lledó <jlledom@member.fsf.org>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ */
+
+#ifndef POSIX_LWIP_HOOKS_H
+#define POSIX_LWIP_HOOKS_H
+
+#if LWIP_IPV4
+
+#include <lwip/ip4_addr.h>
+#include <lwip/netif.h>
+
+struct netif *dhcp_ip4_route_src(const ip4_addr_t *src, const ip4_addr_t *dest);
+
+#endif /* LWIP_IPV4 */
+
+#endif /* POSIX_LWIP_HOOKS_H */
